自学教程 学编程从这里开始

工厂方法模式

《工厂方法模式》|设计模式系列第03篇

系列:创建型模式 · 工厂方法模式(Factory Method Pattern)
关键词:工厂抽象、产品抽象、单一产品族、开闭原则、解耦创建与使用

一、什么是工厂方法模式

工厂方法模式(Factory Method Pattern):定义一个创建产品的抽象工厂接口,让子类决定实例化哪一个产品类。工厂方法将对象实例化延迟到子类。

属于创建型设计模式。
简单理解:
不再由一个大工厂负责生产所有产品,而是一个工厂对应一类产品。抽象工厂定义生产规范,具体工厂负责生产对应的具体产品。

核心意图

把对象创建逻辑和业务使用代码分离,使用者只依赖抽象产品,不用关心 new 哪一个具体类。新增产品时,只需要新增产品类 + 新增对应的工厂类,不修改原有代码,符合开闭原则。

适用场景

  1. 客户端不知道需要创建对象的具体类型
  2. 程序需要动态决定要创建哪一类对象
  3. 产品未来需要持续扩展,新增产品种类
  4. 封装对象创建的复杂逻辑

⚠️ 缺点预警:产品增多时,类数量会成倍增长(每新增一个产品,就要新增产品类 + 工厂类),带来类爆炸。

二、UML结构图

角色划分:

  1. Product(抽象产品):定义产品公共接口
  2. ConcreteProduct(具体产品):实现抽象产品接口
  3. Factory(抽象工厂):声明工厂方法,返回抽象产品
  4. ConcreteFactory(具体工厂):重写工厂方法,返回对应的具体产品实例

三、Java 完整示例

1. 抽象产品 Product

// 抽象产品:日志记录器 Logger
public interface Logger {
    void log(String message);
}

2. 具体产品

// 文件日志
public class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("【文件日志】" + message);
    }
}

// 控制台日志
public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("【控制台日志】" + message);
    }
}

3. 抽象工厂 Factory

// 抽象工厂:日志工厂
public interface LoggerFactory {
    Logger createLogger();
}

4. 具体工厂

// 文件日志工厂
public class FileLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new FileLogger();
    }
}

// 控制台日志工厂
public class ConsoleLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new ConsoleLogger();
    }
}

5. 客户端调用

public class Client {
    public static void main(String[] args) {
        LoggerFactory factory = new FileLoggerFactory();
        Logger logger = factory.createLogger();
        logger.log("工厂方法模式测试日志");

        LoggerFactory factory2 = new ConsoleLoggerFactory();
        Logger logger2 = factory2.createLogger();
        logger2.log("控制台输出日志");
    }
}

客户端只和 Logger、LoggerFactory 抽象打交道,new FileLogger() 被封装在工厂内部。
如果后续新增数据库日志 DBLogger,只需要新增 DBLogger 和 DBLoggerFactory,原有代码完全不用改动。

四、优缺点总结

✅ 优点

  1. 符合开闭原则:新增产品无需修改现有代码
  2. 符合单一职责:创建逻辑放在工厂类,业务类只负责业务
  3. 客户端只依赖抽象,降低耦合

❌ 缺点

  1. 每新增一个产品,都要增加产品类和工厂类,类爆炸
  2. 抽象层次多,代码复杂度上升

五、和简单工厂(静态工厂)对比

  • 简单工厂(静态工厂):一个工厂类,根据参数判断创建不同产品;新增产品要修改工厂内部if逻辑,违反开闭原则。
  • 工厂方法模式:工厂抽象化,每个产品对应独立工厂;新增产品扩展类,不修改旧代码,满足开闭原则。

简单工厂不属于GoF23种设计模式,是工厂方法的简化版本。

六、框架源码应用

  • JDK java.util.Calendar#getInstance()
  • Spring BeanFactory,工厂方法创建Bean实例
  • JDK java.net.URLStreamHandlerFactory

七、小结

工厂方法核心就是:抽象工厂定义生产标准,具体工厂生产具体产品,创建延迟到子类。
适合产品持续扩展场景;产品很少、基本不会新增时,优先简单工厂,避免类爆炸。

标签:

0 条笔记