Python デザインパターン サンプルコード Builder
結城 浩「Java言語で学ぶデザインパターン入門」をPython化
Python3(3.11)で動くソースコード(.pyファイル .ipynbファイル)あります
「anaconda3」on .py「PyCharm」.ipynb「Jupyter Notebook」
(2023-11-18)Python3.11で動作確認済み
【重要な注意】本ソースコードファイルを起動するには第2引数が必要です。ターミナルからPythonを起動するとき,普通はプロンプト「'>'」の後に次のようにタイプします。
>python Builder.py plain(またはhtml)
ターミナルによっては'python'は'python3'になります。ソースコードファイル(スクリプトファイル)名称が第1引数です。第2引数は本プログラムに読み込むオプションです。
「PyCharm」では,次の枠に第2引数を設定します。
メニュー→run→Edit Configurations...→左下矢印と右上矢印の枠
ファイル名→Modify Run Configuration...→左下矢印と右上矢印の枠
画面によっては,Interpreter options: という枠です(左下矢印と右上矢印の枠)
「Jupyter Notebook」では,自己テストの1行目に「sys.argv[1]=」を入れます。「PyCharm」では,この行はありません。「Jupyter Notebook」にこの行を入れるのは,ハードコードと言い,固有名詞や固有な数値をコマンドラインに埋め込むことは本来避けるべきですが,この場合はやむを得ないとしましょう。ちなみにこのコードでは第1引数のような扱いになっていますが,ターミナルのコマンドラインでは第2引数なので混乱しないように。
「sys.argv[1]=」の前かまたは冒頭に「import sys」を忘れないように。
.pyではターミナルから実行されたとき自己テストが実行され,他のファイルから呼ばれたときは自己テストは無視されることも忘れないように。「Jupyter Notebook」では呼ばれる側を上側に置き,下側に参照されるようにします(本記事に関係ないかも)。
Builder ← Director (makeTitle, makeString, makeItems, close) (construct) ↑ ↑ TextBuilder HTMLBuilder (do., getResult) (do., getResult)サンプルは,普通のテキストとHTML コードを同じ手続きでつくります。
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys from abc import ABCMeta, abstractmethod class Builder(metaclass = ABCMeta): #__metaclass__ = ABCMeta @abstractmethod def makeTitle(self, title): pass @abstractmethod def makeString(self, st): pass @abstractmethod def makeItems(self, items): pass @abstractmethod def _close(self): pass class Director(object): def __init__(self, builder): self.builder = builder def construct(self): self.builder.makeTitle("Greeting") self.builder.makeString("朝から昼にかけて") self.builder.makeItems( ["おはようございます。", "こんにちは。"]) self.builder.makeString("夜に") self.builder.makeItems( ["こんばんは。", "おやすみなさい。", "さようなら。"]) self.builder._close() class TextBuilder(Builder): _buffer = [] def makeTitle(self, title): self._buffer.append("===================================\n") self._buffer.append("『{0}』".format(title)) #self._buffer.append("\n") def makeString(self, st): self._buffer.append("■{0}\n".format(st)) #self._buffer.append("\n") def makeItems(self, items): for i in items: self._buffer.append(" ・{0}\n".format(i)) #self._buffer.append("\n") def _close(self): self._buffer.append("===================================\n") def getResult(self): return "\n".join(self._buffer) class HTMLBuilder(Builder): _buffer = [] def makeTitle(self, title): self.title = title self.filename = "{0}.html".format(title) self._buffer.append( "<html><head><title>{0}</title></head><body>\n".format(title)) self._buffer.append("<h1>{0}</h1>\n".format(title)) def makeString(self, st): self.st = st self._buffer.append("<p>{0}</p>\n".format(st)) def makeItems(self, items): self.items = items self._buffer.append("<ul>\n") for i in items: self._buffer.append("<li>{0}</li>\n".format(i)) self._buffer.append("</ul>\n") def _close(self): self._buffer.append("</body></html>\n") def getResult(self): self.writer = open(self.filename, "w") self.writer.write("\n".join(self._buffer)) self.writer.close() return self.filename def main(): if len(sys.argv) == 1: usage() elif sys.argv[1] == "plain": textbuilder = TextBuilder() director = Director(textbuilder) director.construct() result = textbuilder.getResult() sys.stdout.write(result) elif sys.argv[1] == "html": htmlbuilder = HTMLBuilder() director = Director(htmlbuilder) director.construct() filename = htmlbuilder.getResult() sys.stdout.write("{0}が作成されました。".format(filename)) else: usage() def usage(): sys.stdout.write( "Usage:python Builder.py plain;プレーンテキストで文書作成\n") sys.stdout.write( "Usage:python Builder.py html;HTMLファイルで文書作成\n") if __name__=='__main__': main() """標準出力 コマンドライン : plain =================================== 『Greeting』 ■朝から昼にかけて ・おはようございます。 ・こんにちは。 ■夜に ・こんばんは。 ・おやすみなさい。 ・さようなら。 =================================== """
朝から昼にかけて
夜に