概要
Builderパターンは、いくつかの小さなオブジェクトを組み合わせて複雑なオブジェクトを作る場合などに有用。オブジェクトとそのビルダ(オブジェクトを組み立てるためのもの)の両方をクラスで表現する。
ビルダを抽象化、継承させると、抽象化されたビルダクラスのコードを変更するだけで、すべての子のビルダの実装に制限を加えることができる。
以下の例では、ビルドメソッドがすべて「build_」で始まっていれば、どのような抽象ビルダでも扱うことができるように実装している(ディレクタクラス(GeneralDirector))。
実装例
class GeneralBuilder():
def __init__(self, AbstractBuilder):
self.AbstractBuilder = AbstractBuilder
self.build_methods = self.get_build_methods()
self.builder = None
def get_build_methods(self):
method_list = []
for method in dir(self.AbstractBuilder):
if callable(getattr(self.AbstractBuilder, method)) and \
method.startswith("build_"):
method_list.append(method)
return method_list
def build(self):
self.builder.new_object()
for method_name in self.build_methods:
method = getattr(self.builder, method_name)
method()
def get_object(self):
return self.builder.object
class AbstractObjectBuilder():
def __init__(self):
self.object = None
def new_object(self):
self.object = Object(self.__class__.object_name)
def build_children(self):
raise NotImplementedError
class Obj1Builder(AbstractObjectBuilder):
object_name = "obj1"
def build_children(self):
self.object.children = ["obj1-1", "obj1-2"]
class Obj2Builder(AbstractObjectBuilder):
object_name = "obj2"
def build_children(self):
self.object.children = ["obj2-1", "obj2-2"]
class Object():
def __init__(self, name):
self.name = name
self.children = None
def dump(self):
print("Name : ", self.name)
print("Children : ", (", ").join(self.children))
if __name__ == "__main__":
general_builder = GeneralBuilder(AbstractBuilder=AbstractObjectBuilder)
general_builder.builder = Obj1Builder()
general_builder.build()
obj = general_builder.get_object()
obj.dump()
general_builder.builder = Obj2Builder()
general_builder.build()
obj = general_builder.get_object()
obj.dump()