设计模式 # 创建型 # 简单工厂、工厂方法、抽象工厂
三种工厂类创建型设计模式的进化过程
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 总结
- 简单工厂只适用于只有一个工厂生产一个产品的场景,扩展会破坏开闭原则
- 工厂方法适用于多个工厂生产同一类产品的场景,扩展时满足开闭原则
- 抽象工厂适用于多个工厂生产多种类产品的场景,扩展会破坏开闭原则
参考:
📌 软件设计模式概述