BuilderパターンはTemplate Methodパターン(http://ksk77.blogspot.com/2010/11/3-template-method.html)に似ていて、Template Methodの応用と考えたほうが分かりやすいです。
異なる点は:
- Template Method … テンプレートメソッドをスーパークラスが実装している
- Builder … テンプレートメソッドを他のクラス(Director)が実装している
ここでいうテンプレートメソッドは、第3章におけるdisplay()に相当します。
Client(main)はBuilder役を知らず、Director役はBuilderしか知らない、という関係が結合度を小さくすることに寄与するのであります。
ソースコード
日本語エンコード処理まわりが非常に雑なのでその辺は参考にしないでください。
#!/usr/bin/env python # -*- coding: utf8 -*- class Director: def __init__(self, builder): self.builder = builder def construct(self): self.builder.makeTitle("Greeting") self.builder.makeString(u"朝から昼にかけて") self.builder.makeItems([u"おはようございます", u"こんにちは"]) self.builder.makeString(u"夜に") self.builder.makeItems([u"こんばんは", u"おやすみなさい", u"さようなら"]) self.builder.close() class __Builder: def makeTitle(self, title): raise NotImplementedError def makeString(self, string): raise NotImplementedError def makeItems(self, items): raise NotImplementedError def close(self): raise NotImplementedError import StringIO class TextBuilder(__Builder): def __init__(self): self.buf = StringIO.StringIO() def makeTitle(self, title): print >>self.buf, "========================" print >>self.buf, "["+title+"]" print >>self.buf, "" def makeString(self, string): print >>self.buf, u"■"+string print >>self.buf, "" def makeItems(self, items): for i in items: print >>self.buf, u" ・"+i print >>self.buf, "" def close(self): print >>self.buf, "========================" def getResult(self): return self.buf.getvalue() class HTMLBuilder(__Builder): def makeTitle(self, title): try: self.fsock = open(title+".html", 'w') except IOError, (errno, strerror): print "I/O error(%s): %s" % (errno, strerror) print >>self.fsock, "<html><head><title>"+title.encode("utf_8")+"</title></head><body>" print >>self.fsock, "<h1>"+title.encode("utf_8")+"</h1>" def makeString(self, string): print >>self.fsock, "<p>"+string.encode("utf_8")+"</p>" def makeItems(self, items): print >>self.fsock, "<ul>" for i in items: print >>self.fsock, "<li>"+i.encode("utf_8")+"</li>" print >>self.fsock, "</ul>" def close(self): print >>self.fsock, "</body></html>" self.fsock.close() def getResult(self): return self.fsock.name def main(): import sys, getopt opts,args = getopt.getopt(sys.argv[1:],'M:') for key,val in opts: if key == '-M': if val == "plain": textbuilder = TextBuilder() director = Director(textbuilder) director.construct() print textbuilder.getResult() return elif val == "html": htmlbuilder = HTMLBuilder() director = Director(htmlbuilder) director.construct() print htmlbuilder.getResult()+u"が作成されました" return print "Usage: python 7_builder.py -M plain" print "Usage: python 7_builder.py -M html" return if __name__=='__main__': main()
0 件のコメント:
コメントを投稿