• 抽象工厂模式 创建性模式之五


            在看这篇文章之前,请先看看“简单工厂模式”和“工厂方法模式”这两篇博文,会更有助于理解。我们现在已经知道,简单工厂模式就是用一个简单工厂去创建多个产品,工厂方法模式是每一个具体的工厂只生产一个具体的产品,然后这些具体的工厂都以一个抽象的工厂作为基类。

            那么抽象工厂模式是什么呢,抽象工厂模式让一个具体的工厂可以生产多类的产品,也就是它从工厂方法模式种的一厂一产品,变成了一厂多产品的模式。有朋友问了,简单工厂模式不就是一厂多产品么,没错聪明的你发现了问题。但是简单工厂模式,它只有一个唯一的厂。而抽象工厂模式,却可以根据基类的抽象工厂,派生出N多个厂,这就是其本质的区别。

            显然,这三个工厂模式的复杂度是逐渐增加的。这也是我们在进行软件设计的时候做选择的一个重要指标,针对我们具体应用场景的复杂度来选择对应的设计模式。尽量不要用一个复杂的设计模式去解决简单的问题,当然,简单的设计模式也无法很好的适配复杂的业务场景。

    1.示例代码

    1. //抽象工厂代码
    2. #include
    3. using namespace std;
    4. //抽象产品A
    5. class AbstractProductA {
    6. public:
    7. virtual ~AbstractProductA() {}
    8. virtual void Operation() = 0;
    9. };
    10. //具体产品A1
    11. class ProductA1 : public AbstractProductA {
    12. public:
    13. void Operation() {
    14. cout << "ProductA1" << endl;
    15. }
    16. };
    17. //具体产品A2
    18. class ProductA2 : public AbstractProductA {
    19. public:
    20. void Operation() {
    21. cout << "ProductA2" << endl;
    22. }
    23. };
    24. //抽象产品B
    25. class AbstractProductB {
    26. public:
    27. virtual ~AbstractProductB() {}
    28. virtual void Operation() = 0;
    29. };
    30. //具体产品B1
    31. class ProductB1 : public AbstractProductB {
    32. public:
    33. void Operation() {
    34. cout << "ProductB1" << endl;
    35. }
    36. };
    37. //具体产品B2
    38. class ProductB2 : public AbstractProductB {
    39. public:
    40. void Operation() {
    41. cout << "ProductB2" << endl;
    42. }
    43. };
    44. //抽象工厂
    45. class AbstractFactory {
    46. public:
    47. virtual AbstractProductA* CreateProductA() = 0;
    48. virtual AbstractProductB* CreateProductB() = 0;
    49. virtual ~AbstractFactory() {}
    50. };
    51. //具体工厂1:生产产品A1和B1
    52. class ConcreteFactory1 : public AbstractFactory {
    53. public:
    54. ProductA1* CreateProductA() {
    55. return new ProductA1();
    56. }
    57. ProductB1* CreateProductB() {
    58. return new ProductB1();
    59. }
    60. };
    61. //具体工厂2:生产产品A2和B2
    62. class ConcreteFactory2 : public AbstractFactory {
    63. public:
    64. ProductA2* CreateProductA() {
    65. return new ProductA2();
    66. }
    67. ProductB2* CreateProductB() {
    68. return new ProductB2();
    69. }
    70. };
    71. int main() {
    72. //示例代码就不判空了
    73. AbstractFactory* factory1 = new ConcreteFactory1();
    74. // 具体工厂创建对应的具体产品
    75. AbstractProductA* productA_from_factory1 = factory1->CreateProductA(); // 工厂1创建产品A
    76. AbstractProductB* productB_from_factory1 = factory1->CreateProductB(); // 工厂1创建产品B
    77. productA_from_factory1->Operation(); // ProductA1
    78. productB_from_factory1->Operation(); // ProductB1
    79. AbstractFactory* factory2 = new ConcreteFactory2();
    80. AbstractProductA* productA_from_factory2 = factory2->CreateProductA(); // 工厂2创建产品A
    81. AbstractProductB* productB_from_factory2 = factory2->CreateProductB(); // 工厂2创建产品B
    82. productA_from_factory2->Operation(); // ProductA2
    83. productB_from_factory2->Operation(); // ProductB2
    84. delete productA_from_factory1;
    85. delete productA_from_factory2;
    86. delete factory1;
    87. delete productB_from_factory1;
    88. delete productB_from_factory2;
    89. delete factory2;
    90. return 0;
    91. }

    2.组成结构

    工厂方法模式包含的4个角色:

    Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的父类。(这里需要特别说明的是,这个产品的抽象类与工厂的具体类是绑定的,也就是factory1对应一个抽象产品类product1,这是抽象工厂与工厂方法这两个模式最大的区别)
    ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
    Factroy(抽象工厂):在抽象工厂类中声明了工厂方法(Factory method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
    ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。

    3.工厂方法与抽象工厂对比

    工厂方法模式:

    1. 一个抽象产品类,可以派生出多个具体产品类。
    2. 一个抽象工厂类,可以派生出多个具体工厂类。
    3. 每个具体工厂类只能创建一个具体产品类的实例。

    抽象工厂模式:

    1. 一个抽象产品类,可以派生出多个具体产品类。
    2. 一个抽象工厂类,可以派生出多个具体工厂类。
    3. 每个具体工厂类只能创建一个具体产品类的实例。

    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

    4.总结

            所有的工厂模式其核心目的就是为了让对象的创建和使用分离,方便扩展。越是复杂的模式代码层次越多,可读性也变差。因此在选择设计模式的时候需要根据具体的业务场景来确定,不是越复杂的越好,也不是越简单的越好。

     

  • 相关阅读:
    【HTML】HTML基础系列文章小小总结,运用标签写出网页!
    Linux内存管理(二十五):shrink_node
    正大杯黑客马拉松数据解析竞赛
    gitlab 实战
    21.1 stm32使用LTDC驱动LCD--配置说明
    java计算机毕业设计ssm+vue杂货网络销售及配送系统
    常见面试题:http篇
    Python爬虫之Js逆向案例(9)-企ming科技之webpack
    K8s in Action 阅读笔记——【13】Securing cluster nodes and the network
    XXL-JOB核心源码解读及时间轮原理剖析
  • 原文地址:https://blog.csdn.net/Physics_ITBoy/article/details/133376613