【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 パターンでは、複数のインスタンスを同時に生成したい場合に、使用されるようです。