工厂方法模式
1/20/24About 4 min
工厂方法模式(Factory Method Pattern)去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。

主要角色包括:
- 抽象工厂(AbstractFactory):提供了创建产品的接口,调用者通过这个接口来创建产品。
- 具体工厂(ConcreteFactory):实现了抽象工厂中的抽象方法,完成真正的产品实例化。
- 抽象产品(AbstractProduct):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
代码实现
抽象工厂与具体工厂
public abstract class AbstractFactory {
public abstract AbstractProduct createProduct(String name);
}具体工厂继承AbstractFactory,并实现createProduct方法。
public class ConcreteFactoryA extends AbstractFactory {
@Override
public AbstractProduct createProduct(String name) {
return new ProductA();
}
}同样你可以创建一个具体工厂ConcreteFactoryB用于生产ProductB。
抽象产品与具体产品
public abstract class AbstractProduct {
public abstract void work();
}具体产品继承AbstractProduct,并实现work方法。
public class ProductA extends AbstractProduct {
@Override
public void work() {
System.out.println("ProductA work");
}
}同样你可以创建一个具体产品ProductB来实现AbstractProduct接口。
开始生产
public class Client {
public static void main(String[] args) {
AbstractFactory factoryA = new ConcreteFactoryA();
AbstractProduct productA = factoryA.createProduct("A");
productA.work();
AbstractFactory factoryB = new ConcreteFactoryB();
AbstractProduct productB = factoryB.createProduct("B");
productB.work();
}
}通过指定不同的具体工厂我们可以实现不同种类产品的创建。
与其他设计模式的对比
工厂方法模式 vs 简单工厂模式
| 特性 | 工厂方法模式 | 简单工厂模式 |
|---|---|---|
| 工厂结构 | 抽象工厂 + 具体工厂 | 单一工厂类 |
| 开闭原则 | 遵循 | 违反 |
| 扩展性 | 好,添加新产品只需添加新工厂 | 差,添加新产品需修改工厂 |
| 复杂度 | 中 | 低 |
| 适用场景 | 产品种类多且可能扩展 | 产品种类少且变化小 |
工厂方法模式 vs 抽象工厂模式
| 特性 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|
| 创建对象类型 | 单个产品 | 产品家族 |
| 方法数量 | 一个抽象方法 | 多个抽象方法 |
| 产品关系 | 独立 | 相关或依赖 |
| 扩展难度 | 低(添加新产品) | 中(添加新产品家族困难) |
| 适用场景 | 单一产品等级结构 | 多个产品等级结构组成的产品家族 |
工厂方法模式 vs 建造者模式
| 特性 | 工厂方法模式 | 建造者模式 |
|---|---|---|
| 目的 | 创建不同类型的产品 | 创建复杂对象的不同表示 |
| 构建过程 | 简单,直接创建 | 复杂,分步构建 |
| 关注点 | 产品类型 | 产品的构建细节 |
| 扩展性 | 产品类型扩展 | 构建过程扩展 |
| 适用场景 | 产品类型多样 | 产品结构复杂且需要定制 |
总结
工厂方法模式的核心思想是将对象的创建委托给子类,通过抽象工厂接口和具体工厂实现的方式,实现了客户端代码与具体产品类的解耦。
优点
- 遵循开闭原则,添加新产品只需添加新的工厂类,无需修改现有代码
- 客户端只需要知道抽象工厂和抽象产品的接口,不需要知道具体实现
- 实现了单一职责原则,每个工厂类只负责创建一种产品
- 提高了系统的可扩展性和可维护性
缺点
- 增加了系统的复杂度,需要创建多个工厂类
- 客户端需要知道具体的工厂类才能创建对应的产品
- 对于简单的场景,使用工厂方法模式可能过于复杂
适用场景
- 当一个类不知道它所必须创建的对象的类时
- 当一个类希望由它的子类来指定它所创建的对象时
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化时