工厂模式的好处是调用函数的客户端和工厂类交互获得实体,而不是直接和具体的业务类交互,商品的内容更新的时候,客户端无需变动,较为方便的实现了松耦合,高内聚的基本原则。
工厂类的设计模式总共有三种:简单工厂,工厂模式和抽象工厂, 下面将解析一下三种模式的应用场景。
我们假设一种工厂,最开始他是供应宠物包括,猫,狗和鱼,后来随着业务的变更凯斯供应宠物玩具,猫玩具,狗玩具和鱼玩具。
简单工厂
唯一工厂类,一个产品抽象类,工厂类的创建方法依据入参判断并创建具体产品对象。
简单工厂模式的应用场景为,工厂类不会经常更改的情况,产品种类相对固定的情况。

Pros & Cons
Pros:
实现简单
Cons
- 如果增加新的产品类,工厂方法的创建方法中就要增加新的if-else,违背了开闭原则。
- 相当于没新增一种宠物工厂都要停工,重新调整生产线
- 如果增加新的产品类,工厂方法的创建方法中就要增加新的if-else,违背了开闭原则。
工厂方法
多个工厂类,一个产品抽象类,利用多态创建不同的产品对象,避免了大量的if-else判断。

Pros & Cons
Pros
- 新增商品,需要新增工厂,不需要修改原来的工厂,符合开闭原则
- 客户端调用的时候不需要写If-else 的判断逻辑,而是直接按需生成对应的工厂类
Cons
多种产品的组合问题
当有多类产品组合出现的时候,例如N种产品A, M种产品B,则总共需要实现 N*M 种工厂
多种工厂的组合要在客户端完成,如果超过两种则客户端复杂度非常高
站在客户端角度违背高耦合低内聚的原则,于是抽象工厂诞生了
FAQ
为啥不需要写 If-Else
- 通过反射技术来实现,例如
class_a = getattr(module, ’class_a‘)
- 通过反射技术来实现,例如
为什么Factory 不需要依赖 Animal类
- 首先实现代码的时候,最好能明确依赖,方便代码自动提示
- 但是设计的时候可以忽略依赖关系,因为
- 在类型强约束的语言中,例如Java, Rust,可以通过泛型来实现类型泛化
- 在类型弱约束的语言中,例如Python, JS, 则不需要预先定义类型
客户端是否依然需要知道 Animal 和 Factory 两种类型
- 是的
- 工厂模式是违反依赖导致原则?
- 不违反,工厂类是抽象类,并没有依赖细节产品
- 具体的工厂类依赖细节产品或者依赖抽象产品,负责依赖倒置原则
抽象工厂
多个工厂类,多个产品抽象类,同一个工厂实现类可以创建多种类型的产品,减少了工厂子类的数量。

用了抽象工厂,则只需要有三种工厂类,但是如果不用抽象工厂类,需要定义6种工厂,而且还要在客户端自己实现Toys 和 Animal的分别调用。
Pros & Cons
- Pros:
- 在已有产品分类下,增加一种产品搭配很简单,只需要实现一个新的工厂类即可完成
- Cons:
- 如果全部工厂类都要新增加一类产品非常复杂,需要修改全部工厂类
FAQ
抽象工厂类修改这么繁琐,是否违背高耦合低内聚的原则
站在工厂的角度来看,如果是某种产品内部逻辑发生变更,工厂的逻辑不需要变更,是符合低耦合原则的
最复杂的情况是:1. 需要增加一种产品,2.所有的工厂都需要生产这种产品
工厂内部本来就要做这种修改,这是符合高内聚原则的
站在客户端调用的角度来看,业务复杂度升级,但是调用方式保持一致,是符合低耦合原则
参考: