Mamba spirit

Gra55

愿背井离乡、追寻梦想的你归来仍是少年

设计模式 # 创建型 # 简单工厂、工厂方法、抽象工厂

三种工厂类创建型设计模式的进化过程

gra55

1-Minute Read

2019年的最后一天,放一张2019年我最喜欢的照片之一,拍摄于2019年9月4日晚上海迪士尼旋转木马旁

0x00 模式概述

这种三种设计模式都是属于创建型,都是为了将类的创建和使用隔离。GoF 23 种设计模式不包含简单工厂模式,因为简单工厂在扩展的时候需要修改源码,违反了开闭原则

工厂方法模式是简单工厂的升级版,解决了扩展需要修改源码的问题,满足了开闭原则

抽象工厂模式是工厂方法的升级版,解决了工厂方法只能生产一类产品的问题,但是抽象工厂在增加新类型产品的时候会违反开闭原则,这里需要特别注意。

0x01 场景

简单工厂

  • 只有一个工厂生产产品,后期也不会扩展

工厂方法

  • 多个工厂生产同一类产品,后期会扩展更多的工厂

抽象工厂

  • 多个工厂生产多种类型的产品

0x02 解决方案

简单工厂

简单工厂的类图(不是标准的类图,只是凸显一下依赖关系)如下所示,client 需要使用产品类 A 时不直接实例化产品类 A,而是通过 SimpleFactory 工厂类的 createProd() 方法来创建产品类 A 实例。

如果现在需要新增产品类 B,则需要修改 createProd() 方法的源码,这明显违反了开闭原则

+--------------------+              +---------------------------+
|                    |              |       SimpleFactory       |
|      client        +------------->|---------------------------+
|                    |              |    +createProd(prodType)  |
+--------------------+              +---------------------------+

工厂方法

所以出现了工厂方法,工厂方法其实是依赖倒置原则(面向接口编程,不要面向实现编程)的体现,client 不依赖具体的 SimpleFactory,而是依赖一个抽象的工厂 AbstractFactory,具体的工厂继承自 AbstractFactory,实现 createProd() 方法即可。

增加新产品 C 时,只需要新增加 ConcreteFactoryC 类即可,满足开闭原则

+--------------------+              +---------------------------+
|                    |              |       AbstractFactory     |
|      client        +------------->|---------------------------+
|                    |              |        +createProd()      |
+--------------------+              +----+----------------+-----+
                                         ^                ^
                                         |                |
                                         |                |
                          +--------------+-----+     +----+---------------+
                          |  ConcreteFactoryA  |     |  ConcreteFactoryB  |
                          +--------------------+     +--------------------+
                          |    +createProd()   |     |    +createProd()   |
                          +--------------------+     +--------------------+

抽象工厂

抽象工厂在工厂方法的基础上增加了新的产品类型(2 号产品),其他没有太大的区别。但是在扩展新产品类型(3号产品)的时候需要修改已有的代码(AbstractFactory、ConcreteFactoryA、ConcreteFactoryB 都需要增加 createProd3() 方法),破坏了开闭原则

+--------------------+              +---------------------------+
|                    |              |       AbstractFactory     |
|      client        +------------->|---------------------------+
|                    |              |       +createProd1()      |
+--------------------+              |       +createProd2()      |
                                    +----+----------------+-----+
                                         ^                ^
                                         |                |
                                         |                |
                          +--------------+-----+     +----+---------------+
                          |  ConcreteFactoryA  |     |  ConcreteFactoryB  |
                          +--------------------+     +--------------------+
                          |   +createProd1()   |     |   +createProd1()   |
                          |   +createProd2()   |     |   +createProd2()   |
                          +--------------------+     +--------------------+

0x03 总结

  • 简单工厂只适用于只有一个工厂生产一个产品的场景,扩展会破坏开闭原则
  • 工厂方法适用于多个工厂生产同一类产品的场景,扩展时满足开闭原则
  • 抽象工厂适用于多个工厂生产多种类产品的场景,扩展会破坏开闭原则

参考:

📌 软件设计模式概述

Recent Posts

Categories

About

Ordinary but not mediocre, fighting