- Creational design pattern
- 複数クラスのインスタンスを切り替える(参照先をファイルにしたりDBにしたり)ときに使う
- 利用者側のコード変更を最小限に留めることが目的なのかな
- 2種類の抽象クラス
- Productクラス: ファクトリが生成するオブジェクトのインターフェース
- Creatorクラス: Product型のオブジェクトを返すファクトリメソッドを持つクラス
- 2種類の
- ConcreteProductクラス: 実際に生成されるオブジェクト
- ConcreteCreatorクラス: ファクトリメソッドの使用者
- 使用者はConcreteCreator型オブジェクトの持つcreate()を使ってProduct型のポインタを受け取る
- ConcreteProduct型ではなくProduct型のポインタとして受け取ることで,使用者はサブクラスの存在を意識する必要がなくなる
header
/*** Abstract classes ***/ class Product { public: virtual int anOperation() = 0; }; class Creator { public: virtual Product* create() = 0; }; /*** Concrete classes for index 0 ***/ class ConcreteProduct0 : public Product { public: ConcreteProduct0(); int anOperation() override; }; class ConcreteCreator0 : public Creator { public: Product* create() override; }; /*** Concrete classes for index 1 ***/ class ConcreteProduct1 : public Product { public: ConcreteProduct1(); int anOperation() override; }; class ConcreteCreator1 : public Creator { public: Product* create() override; };
source
#include <iostream> #include "FactoryMethod.hh" ConcreteProduct0::ConcreteProduct0() { std::cout << " Constructor (ConcreteProduct0)" << std::endl; } int ConcreteProduct0::anOperation() { std::cout << " Operation (ConcreteProduct0)" << std::endl; return 0; } Product* ConcreteCreator0::create() { return new ConcreteProduct0(); } ConcreteProduct1::ConcreteProduct1() { std::cout << " Constructor (ConcreteProduct1)" << std::endl; } int ConcreteProduct1::anOperation() { std::cout << " Operation (ConcreteProduct1)" << std::endl; return 1; } Product* ConcreteCreator1::create() { return new ConcreteProduct1(); } int main() { { std::cout << "ConcreteCreator0:" << std::endl; auto creator{ConcreteCreator0()}; auto product{creator.create()}; product->anOperation(); } { std::cout << "ConcreteCreator1:" << std::endl; auto creator{ConcreteCreator1()}; auto product{creator.create()}; product->anOperation(); } return 0; }