yiskw note

機械学習やプログラミングについて気まぐれで書きます

【Python】Factory / Factory Method / Abstract Factory の違い


概要

今回は、オブジェクトの生成方法に関するデザインパターンである、 Factory パターン、Factory Method パターン、Abstract Factory パターンの違いについてまとめました。

これらは混同やすく、自分も違いをしっかりできていなかったのですが、 最近やっとこれらの違いについて整理がついてきたので、Pythonのコードとともにメモを残しておきます。

間違いも含まれるかと思いますので、その場合はコメントにてご教授いただけると幸いです。

Factory パターンとは

Factory パターンは、オブジェクトの生成を抽象化するためのデザインパターンです。 Factory パターンでは、インスタンス生成の責務をfactoryクラスに持たせることで、インスタンスを生成する方法をカプセル化して、異なるクラスのインスタンスを生成することができます。

class Factory:
    def create_product(self, product_type):
        if product_type == "A":
            return ConcreteProductA()
        elif product_type == "B":
            return ConcreteProductB()


class Product:
    pass


class ConcreteProductA(Product):
    pass


class ConcreteProductB(Product):
    pass


def main():
    factory = Factory()
    product_a = factory.create_product("A")
    product_b = factory.create_product("B")

また上記コードでは、クラスの選択にif文を使っていますが、辞書などを活用することで、if文を排除することも可能です。

Factoryパターンは、特定の目的でインスタンスを作成したい場合によく使われるようです。(例えば、機械学習モデルを作成したい場合など)

Factory Method パターン

Factory Method パターンは、Factory パターンの一種で、どのクラスのインスタンスを生成するかをFactoryのサブクラス(concrete factory)に任せることで、 特定の用途に特化したインスタンスの生成を行うことができます。

class Product:
    pass


class ConcreteProductA(Product):
    pass


class ConcreteProductB(Product):
    pass


class Factory:
    def factory_method(self):
        pass


class ConcreteFactoryA(Factory):
    def factory_method(self):
        return ConcreteProductA()


class ConcreteFactoryB(Factory):
    def factory_method(self):
        return ConcreteProductB()


def main():
    factory_a = ConcreteFactoryA()
    factory_b = ConcreteFactoryB()

    product_a = factory_a.factory_method()
    product_b = factory_b.factory_method()

Factory Method パターンは、concrete factoryごとにインスタンスの生成方法を決めておけるので、 インスタンスを作成する際に、多くの依存関係や設定が必要な場合に使用されるようです。

Abstract Factory とは

Abstract Factoryパターンは、Factory Methodパターンと似ていますが、複数の関連したオブジェクトを一度に生成するために使用されます。

このパターンでは、インスタンス生成の責務をfactoryクラスに持たせ、複数のインスタンスの生成方法をfactoryクラスのサブクラス(concrete factory)に任せることで、 インスタンスの集合を、特定のクラスを指定することなく生成できます。

class AbstractFactory:
    def create_product_a(self):
        pass

    def create_product_b(self):
        pass


class ConcreteFactoryA(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA()

    def create_product_b(self):
        return ConcreteProductB()


class ConcreteFactoryB(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductC()

    def create_product_b(self):
        return ConcreteProductD()


class ProductA:
    pass


class ProductB:
    pass


class ConcreteProductA(ProductA):
    pass


class ConcreteProductB(ProductB):
    pass


class ConcreteProductC(ProductA):
    pass


class ConcreteProductD(ProductB):
    pass


def main():
    factory_a = ConcreteFactoryA()
    factory_b = ConcreteFactoryB()

    product_a = factory_a.create_product_a()
    product_b = factory_a.create_product_b()

    product_c = factory_b.create_product_a()
    product_d = factory_b.create_product_b()

Abstract Factory パターンでは、複数のインスタンスを同時に生成したい場合に、使用されるようです。

Reference

Difference between Factory and Abstract Factory | bitMountn