Python デザインパターン サンプルコード Prototype
結城 浩「Java言語で学ぶデザインパターン入門」をPython化
Python3(3.11)で動くソースコード(.pyファイル .ipynbファイル)あります
「anaconda3」on .py「PyCharm」.ipynb「Jupyter Notebook」
(2023-11-18)Python3.11で動作確認済み
Product ← Manager (use, createClone) (register, create) ↑ ↑ MessageBox UnderlinePen (use, createClone) (use, createClone)class Product は,テンプレートであり抽象クラスです。Java ではインターフェイスです。
upen = UnderlinePen("~") manager.register("strong message", upen) p1 = manager.create("strong message") p1.use("Hello, world.")最初は,装飾パターンを選ぶクラスを,装飾文字をパラメータとしてインスタンス化しています。次にこのインスタンスを名前を付けて登録しています。そしてこの名前によりオブジェクトをつくり(コピーし),そのオブジェクトを使って装飾される文字列をパラメータにして具体的に装飾するメソッドを呼んでいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys from abc import ABCMeta, abstractmethod import copy class Product(metaclass = ABCMeta): @abstractmethod def use(self, s): pass @abstractmethod def createClone(self): pass class Manager(object): showcase = {} def register(self, name, proto): self.showcase[name] = proto def create(self, protoname): p = self.showcase.get(protoname) return p.createClone() class MessageBox(Product): def __init__(self, decochar): self.decochar = decochar def use(self, s): length = len(s) deco = self.decochar * (length + 4 ) sys.stdout.write("{}\n".format(deco)) sys.stdout.write("{} {} {}\n".format(self.decochar,s,self.decochar)) sys.stdout.write("{}\n".format(deco)) def createClone(self): p = copy.deepcopy(self) return p class UnderlinePen(Product): def __init__(self, ulchar): self.ulchar = ulchar def use(self, s): length = len(s) sys.stdout.write('"{}"\n' .format(s)) sys.stdout.write(" {}\n".format(self.ulchar * length)) def createClone(self): p = copy.deepcopy(self) return p def main(): # 準備 manager = Manager() upen = UnderlinePen("~") mbox = MessageBox("*") sbox = MessageBox("/") manager.register("strong message", upen) manager.register("warning box", mbox) manager.register("slash box", sbox) # 生成 p1 = manager.create("strong message") p1.use("Hello, world.") p2 = manager.create("warning box") p2.use("Hello, world.") p3 = manager.create("slash box") p3.use("Hello, world.") if __name__== '__main__': main() """標準出力 "Hello, world." ~~~~~~~~~~~~~ ***************** * Hello, world. * ***************** ///////////////// / Hello, world. / ///////////////// """