抽象工厂:不同的 Factory 对于不同的任务有不同的实现方式。
例如,同样是数据库,不同数据库 ORM 框架的实现方式不同。
生产水果时,不同水果生产工厂包含着很多内容,如:生产对应水果、生产对应水果包装。苹果工厂,不仅要生产苹果,还要生产小包装;西瓜工厂,不仅要生产西瓜,还要生产大包装。即,工厂之间有不止一个相同方法的不同实现,为此,将这些方法都放到工厂接口/抽象类中,各个工厂再重写实现内部内容。这种实现模式叫做抽象工厂模式。
例子 2:南北地区的苹果生产是不同的,梨子也是不同的。为了解决这个问题,需要创建南方工厂和北方工厂,南方工厂实现南方的苹果梨子生产方法,北方工厂实现北方的苹果梨子生产方法。
1 模式结构

2 具体实现
public interface IFactory {
Fruit createFruit();
Box createBox();
}
public class AppleFactory implements IFactory {
// @Override ...
}
public class PearFactory implements IFactory {
// @Override ...
}调用者
public class User {
private void getFruit(){
IFactory factory = new AppleFactory();
Fruit apple = factory.createFruit();
Box box = factory.createBox();
apple.eat();
box.destroyBox();
}
}抽象工厂模式主要用于替换一系列方法。例如将程序中的 SQL Server 数据库整个替换为 Access 数据库,使用抽象方法模式的话,只需在 IFactory 接口中定义好增删改查四个方法,让 SQLFactory 和 AccessFactory 实现此接口,调用时直接使用 IFactory 中的抽象方法即可,调用者无需知道使用的什么数据库,我们就可以非常方便的整个替换程序的数据库,并且让客户端毫不知情。
抽象工厂模式很好的发挥了开闭原则、依赖倒置原则,但缺点是抽象工厂模式太重了,如果 IFactory 接口需要新增功能,则会影响到所有的具体工厂类。使用抽象工厂模式,替换具体工厂时只需更改一行代码,但要新增抽象方法则需要修改所有的具体工厂类。所以抽象工厂模式适用于增加同类工厂这样的横向扩展需求,不适合新增功能这样的纵向扩展。
3 应用场景
场景 1:需要与多个不同系列的相关产品交互,但是由于无法提前获取相关信息,或者出于对未来扩展性的考虑,你不希望代码基于产品的具体类进行构建。
4 优缺点
优点
- 你可以确保同一工厂生成的产品相互匹配。
- 你可以避免客户端和具体产品代码的耦合。
- 单一职责原则。你可以将产品生成代码抽取到同一位置,使得代码易于维护。
- 开闭原则。向应用程序中引入新产品变体时,你无需修改客户端代码。
缺点
- 由于采用该模式需要向应用中引入众多接口和类,代码可能会比之前更加复杂。