工厂方法模式(Factory Method)
一个特定功能,往往有多种实现方式,但是很难有某一个实现可以适用于所有情况,因此往往需要根据特定的场景选择不同的实现。试想:把选择具体实现的代码放在业务中会发生什么?每当我们需要一个新的功能拓展时,就要改动业务代码,但是这样违背了OCP,引入工厂方法模式可以解决这样的问题。
意图(Intent)
工厂方法模式:一种创建者模式,提供了一个创建类的接口,具体创建该类的哪种实现类,由传入的子类工厂决定
工厂方法模式其实就是对子类构造的封装。
工厂是对创建类的接口一种隐喻。我们把需求传递给工厂,工厂就能构造出一个相对应的子类
可以直接在工厂中加入产品的方法,这样就可以直接通过工厂使用产品方法,而不需要再调用产品
结构(Structure)
工厂方法模式的结构图如下:
CreatorProduct
是Product
的工厂,它包含了一个构造Product
的方法和Product
内部的方法ConcreProductA
和ConcreProductB
是Product
的实现类,每个类都有一个对应的工厂子类- 工厂接口只负责定义工厂的行为,工厂的具体行为,由对应实现类的子类负责实现
为什么需要工厂方法模式?
工厂方法模式的必要性可以从多个维度解释,本文提供了其中两种解释:
-
首先我们要明确一个概念,客户端只通过接口使用产品,而不需要知道其中的细节,我们作为开发者也不想让客户端知道这些细节。工厂方法模式就可以理解为一种创建产品的接口,这个产品内部可能需要各种各样的属性,来实现产品的功能,客户端传入的数据怎么分配在该产品的属性中不是客户端需要知道的。
-
而从OCP的角度来看,如果没有工厂接口,每次新增加一个产品类,我们就要重新在客户端加入一段代码,实现该产品的创建,这个显然违背了OCP。
实现方式(implement)
- 为要实现的功能创建一个接口或者抽象类
- 为这个接口或抽象类创建一个工厂接口
- 用不同的子类实现这个接口或抽象类
- 为每个子类编写工厂接口的实现工厂类
- 在创建子类实例时,调用对应的工厂类的方法即可
优缺点(Pros & Cons)
-
可以避免客户端和具体产品的高耦合
-
保证SRP,选择并创建具体产品的工作交给工厂
-
保证OCP,当有新的实现类的时候,只需要继承父类即可,不用改变客户端代码
-
代码过于复杂,并且可能造成类爆炸
抽象工厂(Abstract Factory)
工厂方法模式为我们提供了每种产品的实现方法,解耦了客户端和具体产品的紧密关联,但是过于冗杂的类会让我们对项目管理的难度大大提升,为了解决这个问题,我们可以使用抽象工厂模式。
意图(Intent)
抽象工厂是对不同产品的抽象。就像我们可以通过学生的共有特性抽象出学生类一样,抽象工厂将具有某种相同特性的产品抽象到了一个类,这个类中有多个工厂方法。
工厂方法不是一个类!上文似乎把工厂方法作为一个类在讲解,这其实是为了简化工厂方法模式的讲解,而只在类中声明了工厂方法一个方法。
举个例子来讲,一套衣服包括了上衣和裤子。那么一个抽象工厂中就包含了两个工厂方法,一个用于生产上衣,一个用于生产裤子。
结构(Structure)
抽象工厂的结构图如下:
- 抽象工厂负责建造两种产品:
ProductA
和ProductB
- 定义一个抽象工厂的接口
- 根据产品的不同风格实现抽象工厂接口
为什么需要抽象工厂模式?
抽象工厂模式是对工厂方法模式的一种拓展,一个抽象工厂类应该包含多种工厂方法,这样可以让类的管理更有逻辑性,也能对相似风格的不同产品进行抽象。
优缺点(Pros & Cons)
-
具有工厂方法的优点
-
可以保证来自同一工厂的不同产品是兼容的
-
可以减少工厂方法带来的类爆炸
-
使类的管理更清晰