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 件のコメント:
コメントを投稿