Python

Python デザインパターンを学ぶ Builderパターン

概要

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()