工厂方法模式(Factory Method Pattern)是一种创建型设计模式,其核心思想是将对象的创建过程延迟到子类,通过抽象化工厂接口解决简单工厂模式中的扩展性问题。以下是该模式的详细解析:
一、核心定义与设计目标
-
定义
定义一个用于创建对象的接口,但让子类决定实例化哪个具体类。工厂方法模式将实例化操作延迟到子类,实现创建逻辑与使用逻辑的解耦。 -
设计目标
- 开闭原则:支持新增产品类型时无需修改现有代码。
- 多态性与扩展性:通过子类化工厂实现动态扩展。
- 依赖倒置:客户端仅依赖抽象接口,而非具体实现。
二、模式结构与角色划分
-
核心角色([6] [13])
- 抽象产品(Product):定义产品的公共接口(如
Shape接口)。 - 具体产品(Concrete Product):实现抽象产品的具体类(如
Circle、Rectangle)。 - 抽象工厂(Creator):声明工厂方法(如
createProduct()),返回抽象产品类型。 - 具体工厂(Concrete Creator):重写工厂方法,返回具体产品实例(如
CircleFactory)。
- 抽象产品(Product):定义产品的公共接口(如
-
UML类图示例
+-------------------+ +-------------------+ | Creator | | Product | +-------------------+ +-------------------+ | +factoryMethod() |<|------|>| +operation() | +-------------------+ +-------------------+ ▲ ▲ | | +-------------------+ +-------------------+ | ConcreteCreatorA | | ConcreteProductA | +-------------------+ +-------------------+ | +factoryMethod() |─────────>| +operation() | +-------------------+ +-------------------+
三、与简单工厂模式的对比
| 特性 | 简单工厂模式 | 工厂方法模式 |
|---|---|---|
| 扩展性 | 新增产品需修改工厂类(违反开闭原则) | 新增产品只需添加子类(符合开闭原则) |
| 工厂职责 | 集中处理所有产品创建逻辑 | 分散到子类,每个工厂负责单一产品 |
| 适用场景 | 产品类型固定、逻辑简单 | 产品类型动态扩展、系统需高灵活性 |
| 代码复杂度 | 低(单工厂类) | 较高(多工厂子类) |
四、优缺点分析
优点
- 符合开闭原则:新增产品类型只需扩展子类,无需修改已有代码。
- 解耦创建与使用:客户端仅依赖抽象接口,降低耦合。
- 支持多态性:通过子类工厂实现不同产品的动态创建。
缺点
- 类数量增加:每新增一个产品需对应新增一个工厂子类。
- 复杂性提升:对简单场景可能引入不必要的抽象。
- 需继承体系支持:若产品族需跨多个维度组合,需引入抽象工厂模式。
五、适用场景
- 动态扩展需求:如日志系统需支持新增日志类型(文件、数据库、控制台。
- 框架设计:允许用户自定义对象创建逻辑(如 Spring 的
BeanFactory)。 - 跨平台组件:不同平台的 UI 控件(按钮、文本框)通过子类工厂实现。
- 对象创建复杂:需封装复杂初始化过程(如数据库连接池。
六、代码实现示例(Java)
// 抽象产品
interface Shape {
void draw();
}
// 具体产品
class Circle implements Shape {
@Override public void draw() { System.out.println("绘制圆形"); }
}
// 抽象工厂
interface ShapeFactory {
Shape createShape();
}
// 具体工厂
class CircleFactory implements ShapeFactory {
@Override public Shape createShape() { return new Circle(); }
}
// 客户端
public class Client {
public static void main(String[] args) {
ShapeFactory factory = new CircleFactory();
Shape shape = factory.createShape();
shape.draw(); // 输出:绘制圆形
}
}
七、实际应用案例
-
日志记录系统
- 抽象产品:
Logger接口定义log()方法。 - 具体产品:
FileLogger、DatabaseLogger。 - 工厂子类:
FileLoggerFactory、DatabaseLoggerFactory。
- 抽象产品:
-
游戏角色创建
- 抽象产品:
Character接口定义attack()方法。 - 具体产品:
Warrior、Mage。 - 工厂子类:
WarriorFactory、MageFactory。
- 抽象产品:
八、总结
工厂方法模式通过将对象创建逻辑分散到子类,解决了简单工厂模式违反开闭原则的问题,适用于需要动态扩展产品类型的场景。其代价是增加了类的数量,但通过合理的抽象设计可显著提升系统的灵活性和可维护性。在实际开发中,需根据需求权衡是否引入该模式。
2137

被折叠的 条评论
为什么被折叠?



