设计模式中的抽象工厂模式&c++

属于创建型设计模式中的一种。

这里首先介绍简单工厂模式(Simple Factory)

概述:

该模式一上来就是一个具体的工厂类,供用户调用来创建具体的产品。产品有抽象类,从抽象类中派生出多个具体产品。然后在工厂类中根据参数动态生成具体产品类对象。
demo:(代码来源:http://www.cnblogs.com/jerry19880126/archive/2012/08/08/2628321.html

  
  
  1. 简单工厂模式
  2. #include <iostream>
  3. using namespace std;
  4. // 简单工厂模式
  5. // 抽象产品
  6. class AbstractProduct
  7. {
  8. public:
  9. virtual void getProductsName() = 0;
  10. };
  11. // 具体产品1
  12. class ConcreteProduct1: public AbstractProduct
  13. {
  14. public:
  15. void getProductsName()
  16. {
  17. cout << "ConcreteProduct1" << endl;
  18. }
  19. };
  20. // 具体产品2
  21. class ConcreteProduct2: public AbstractProduct
  22. {
  23. public:
  24. void getProductsName()
  25. {
  26. cout << "ConcreteProduct2" << endl;
  27. }
  28. };
  29. // 具体的工厂(没有抽象工厂)
  30. class ConcreteFactory
  31. {
  32. public:
  33. AbstractProduct* getProductObject(int flag)
  34. {
  35. if(flag == 1)
  36. {
  37. return new ConcreteProduct1();
  38. }
  39. else if(flag == 2)
  40. {
  41. return new ConcreteProduct2();
  42. }
  43. else
  44. {
  45. return 0;
  46. }
  47. }
  48. };
  49. int main()
  50. {
  51. ConcreteFactory f;
  52. AbstractProduct* p1 = f.getProductObject(1);
  53. AbstractProduct* p2 = f.getProductObject(2);
  54. p1->getProductsName();
  55. p2->getProductsName();
  56. delete p1;
  57. delete p2;
  58. return 0;
  59. }

  1. (普通)工厂模式(Factory)

与简单工厂模式换汤不换药,只是把工厂也“抽象”了,UML图如下所示:

区别与简单工厂模式,普通工厂模式将工厂类也进行了抽象,提供了工厂类的抽象类。并且将简单工厂模式中由用户提供参数后台进行创建何种对象的创建的情况进行了修改。每个具体的工厂类负责创建一个现实的产品。这样,客户端就可以决定调用哪一个工厂类,然后就不用后台进行判断选择具体创建那个产品了。

这里假定有两个ConcreteFactory,一个是ConcreteFactory1,只生产ConcreteProduct1产品,另一个是ConcreteFactory2,只生产ConcreteProduct2产品。

代码如下:

 
 
  1. 普通工厂模式
  2. #include <iostream>
  3. using namespace std;
  4. //普通工厂模式
  5. //抽象产品
  6. class AbstractProduct
  7. {
  8. public:
  9.    virtual void getProductName() = 0;
  10. };
  11. //具体产品1
  12. class ConcreteProduct1: public AbstractProduct
  13. {
  14. public:
  15.    void getProductName()
  16.    {
  17.        cout << "ConcreteProduct1" << endl;
  18.    }
  19. };
  20. //具体产品2
  21. class ConcreteProduct2: public AbstractProduct
  22. {
  23. public:
  24.    void getProductName()
  25.    {
  26.        cout << "ConcreteProduct2" << endl;
  27.    }
  28. };
  29. //抽象工厂
  30. class AbstractFactory
  31. {
  32. public:
  33.    virtual AbstractProduct* getProduct() = 0;
  34. };
  35. //具体工厂1
  36. class ConcreteFactory1: public AbstractFactory
  37. {
  38. public:
  39.    AbstractProduct* getProduct()
  40.    {
  41.        return new ConcreteProduct1();
  42.    }
  43. };
  44. //具体工厂2
  45. class ConcreteFactory2: public AbstractFactory
  46. {
  47. public:
  48.    AbstractProduct* getProduct()
  49.    {
  50.        return new ConcreteProduct2();
  51.    }
  52. };
  53. int main()
  54. {
  55.    AbstractFactory* f1 = new ConcreteFactory1();
  56.    AbstractFactory* f2 = new ConcreteFactory2();
  57.    f1->getProduct()->getProductName();
  58.    f2->getProduct()->getProductName();
  59.    delete f1, f2;
  60.    return 0;
  61. }

最后是:

抽象工厂模式(Abstract Factory)

抽象工厂模式其实是之前正常工厂模式的进化,或者说是多了些内容而已。

同样的,该模式中有一个抽象的工厂类,区别之前的是抽象工厂中生产的产品多了一个。所以嘛,如图所示,继承自他的具体类工厂也就都变成了包含两个成员函数,负责对产品的生产。

抽象产品类也是有两个A(A1,A2),B(B1,B2),每个产品有两个不同的版本。对应的两个具体工厂类。

具体工厂类1负责生产A1,B1  .

具体工厂类2负责生产A2,B2.  


应用用例:

这样的 抽象工厂模式可以利用在这样的场景下:

比如如今流行的windows跟mac两版本电脑。我们可能在界面层会使用两套独立的界面包。这时候,我们就可以创建抽象工厂类WidgetFactory,内含按钮,滚动条,树控件等虚接口。然后派生出两套具体的工厂类winWidgetFactory,macWidgetFactory。然后正对某个控件,譬如说按钮,为其定义一个抽象类,然后同样派生出win跟mac两款具体类。滚动条也进行同样的定制。这样,就可以供两款具体工厂类进行调用了。使用时,针对某一款系列平台,使用对应的工厂类就可以正确选择匹配的各个具体产品了。

demo实例:

 
 
  1. 抽象工厂模式
  2. #include <iostream>
  3. using namespace std;
  4. // 抽象工厂模式
  5. // 抽象产品A
  6. class AbstractProductA
  7. {
  8. public:
  9.         virtual void getProductName() = 0;
  10. };
  11. // 具体产品A1
  12. class ConcreteProductA1: public AbstractProductA
  13. {
  14. public:
  15.         void getProductName()
  16.         {
  17.                   cout << "ConcreteProductA1" << endl;
  18.         }
  19. };
  20. // 具体产品A2
  21. class ConcreteProductA2: public AbstractProductA
  22. {
  23. public:
  24.         void getProductName()
  25.         {
  26.                   cout << "ConcreteProductA2" << endl;
  27.         }
  28. };
  29. // 抽象产品B
  30. class AbstractProductB
  31. {
  32. public:
  33.         virtual void getProductName() = 0;
  34. };
  35. // 具体产品B1
  36. class ConcreteProductB1: public AbstractProductB
  37. {
  38. public:
  39.         void getProductName()
  40.         {
  41.                   cout << "ConcreteProductB1" << endl;
  42.         }
  43. };
  44. // 具体产品B2
  45. class ConcreteProductB2: public AbstractProductB
  46. {
  47. public:
  48.         void getProductName()
  49.         {
  50.                   cout << "ConcreteProductB2" << endl;
  51.         }
  52. };
  53. // 抽象工厂
  54. class AbstractFactory
  55. {
  56. public:
  57.         virtual AbstractProductA* getProductA() = 0;
  58.         virtual AbstractProductB* getProductB() = 0;
  59. };
  60. // 具体工厂1
  61. class ConcreteFactory1: public AbstractFactory
  62. {
  63.         AbstractProductA* getProductA()
  64.         {
  65.                   return new ConcreteProductA1;
  66.         }
  67.         AbstractProductB* getProductB()
  68.         {
  69.                   return new ConcreteProductB1;
  70.         }
  71. };
  72. // 具体工厂2
  73. class ConcreteFactory2: public AbstractFactory
  74. {
  75.         AbstractProductA* getProductA()
  76.         {
  77.                   return new ConcreteProductA2;
  78.         }
  79.         AbstractProductB* getProductB()
  80.         {
  81.                   return new ConcreteProductB2;
  82.         }
  83. };
  84. int main()
  85. {
  86.         AbstractFactory *f1 = new ConcreteFactory1();
  87.         AbstractFactory *f2 = new ConcreteFactory2();
  88.         f1->getProductA()->getProductName();
  89.         f1->getProductB()->getProductName();
  90.         f2->getProductA()->getProductName();
  91.         f2->getProductB()->getProductName();
  92.         delete f1, f2;
  93.         return 0;
  94. }


优点:

1.分离了具体的类。客户可以通过抽象工厂对工厂类进行访问,以及通过抽象产品接口调用具体的产品了。

2.可以很方便的切换产品系列,像上面阐述的win系列跟mac系列界面kit的切换。

3.保证使用过程中使用的是统一风格或者说同一系列的产品,不会导致混乱的调用。

缺点:

无论是扩展抽象共产还是生产新种类的产品,都需要改变所有的具体类。很是繁琐。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值