Factory Method

  • インターフェイスを介してオブジェクトの生成を行うことで、オブジェクト間の結合度を弱める。
    • クラスの切り替えや新規クラスの追加を柔軟に行えるようにする。
  • Product の種類を増やす場合、新しいクラスを定義すれば良い。既存のファクトリメソッドを修正する必要はない。
  • Product 毎にファクトリクラスを用意する必要がある。

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. // "Product" abstract class
  5. class Product {
  6. public:
  7. virtual ~Product() {
  8. cout << "Product Destructor" << endl;
  9. }
  10. virtual void Operation() = 0;
  11. virtual void Destroy() = 0;
  12. };
  13.  
  14. // "ConcreteProduct" class
  15. class ProductA : public Product {
  16. public:
  17. virtual ~ProductA() {
  18. cout << "ProductA Destructor" << endl;
  19. }
  20. virtual void Operation() {
  21. cout << "ProductA Operation" << endl;
  22. }
  23. virtual void Destroy() {
  24. delete this;
  25. }
  26. };
  27.  
  28. // "ConcreteProduct" class
  29. class ProductB : public Product {
  30. public:
  31. virtual ~ProductB() {
  32. cout << "ProductB Destructor" << endl;
  33. }
  34. virtual void Operation() {
  35. cout << "ProductB Operation" << endl;
  36. }
  37. virtual void Destroy() {
  38. delete this;
  39. }
  40. };
  41.  
  42. // "Factory" abstract class
  43. class Factory {
  44. public:
  45. virtual Product* CreateProduct() = 0;
  46. };
  47.  
  48. // "ConcreteFactory" class
  49. class FactoryA : public Factory {
  50. public:
  51. Product* CreateProduct() {
  52. return new ProductA;
  53. }
  54. };
  55.  
  56. // "ConcreteFactory" class
  57. class FactoryB : public Factory {
  58. public:
  59. Product* CreateProduct() {
  60. return new ProductB;
  61. }
  62. };
  63.  
  64.  
  65. // "client"
  66. int main(int argc, char **argv) {
  67. Product *product;
  68. Factory *factory;
  69.  
  70. for (int i=0; i<2; ++i) {
  71. if (i == 0) {
  72. factory = new FactoryA();
  73. } else {
  74. factory = new FactoryB();
  75. }
  76. product = factory->CreateProduct();
  77. product->Operation();
  78. product->Destroy();
  79. delete factory;
  80. }
  81.  
  82. return 0;
  83. }
  84.  

出力
ProductA Operation
ProductA Destructor
Product Destructor
ProductB Operation
ProductB Destructor
Product Destructor


Product の delete を、Factory のデストラクタで行う
(複数 Product を生成した場合も、全部破棄する)
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. // "Product" abstract class
  6. class Product {
  7. public:
  8. virtual ~Product() {
  9. cout << "Product Destructor" << endl;
  10. }
  11. virtual void Operation() = 0;
  12. };
  13.  
  14. // "ConcreteProduct" class
  15. class ProductA : public Product {
  16. public:
  17. virtual ~ProductA() {
  18. cout << "ProductA Destructor" << endl;
  19. }
  20. virtual void Operation() {
  21. cout << "ProductA Operation" << endl;
  22. }
  23. };
  24.  
  25. // "ConcreteProduct" class
  26. class ProductB : public Product {
  27. public:
  28. virtual ~ProductB() {
  29. cout << "ProductB Destructor" << endl;
  30. }
  31. virtual void Operation() {
  32. cout << "ProductB Operation" << endl;
  33. }
  34. };
  35.  
  36. // "Factory" abstract class
  37. class Factory {
  38. public:
  39. virtual ~Factory() {
  40. vector<Product*>::iterator it = m_prods.begin();
  41. while (it != m_prods.end()) {
  42. delete *it;
  43. ++it;
  44. }
  45. };
  46. virtual Product* CreateProduct() = 0;
  47. protected:
  48. vector<Product*> m_prods;
  49. };
  50.  
  51. // "ConcreteFactory" class
  52. class FactoryA : public Factory {
  53. public:
  54. Product* CreateProduct() {
  55. Product* prod = new ProductA;
  56. m_prods.push_back(prod);
  57. return prod;
  58. }
  59. };
  60.  
  61. // "ConcreteFactory" class
  62. class FactoryB : public Factory {
  63. public:
  64. Product* CreateProduct() {
  65. Product *prod = new ProductB;
  66. m_prods.push_back(prod);
  67. return prod;
  68. }
  69. };
  70.  
  71.  
  72. // "client"
  73. int main(int argc, char **argv) {
  74. Product *product;
  75. Factory *factory;
  76.  
  77. for (int i=0; i<2; ++i) {
  78. if (i == 0) {
  79. factory = new FactoryA();
  80. } else {
  81. factory = new FactoryB();
  82. }
  83. product = factory->CreateProduct();
  84. product->Operation();
  85. delete factory;
  86. }
  87.  
  88. return 0;
  89. }
  90.  


参考サイト

デザインパターンを“喩え話”で分かり易く理解する
http://www.netlaputa.ne.jp/~hijk/study/oo/designpattern.html



デザインパターンの骸骨たち
http://www002.upp.so-net.ne.jp/ys_oota/mdp/
最終更新:2012年01月29日 17:19