工厂方法模式通过分离“创建什么”和“怎么创建”,让客户端只依赖抽象产品和抽象工厂,由具体工厂子类封装构造逻辑与依赖细节,实现解耦与可扩展。

工厂方法模式通过把“创建什么”和“怎么创建”分开,让调用方只关心需要什么对象,而不必了解构造细节、依赖关系或条件分支。它不直接 new 实例,而是把创建逻辑下沉到专门的工厂子类里,从而真正实现解耦。
明确产品接口与具体实现
先定义统一的产品抽象(如接口或抽象类),所有具体类型都实现它。比如日志记录器可以有 FileLogger、DBLogger、CloudLogger,它们都实现 Logger 接口。这样客户端代码只面向 Logger 编程,不绑定任何具体类。
- 避免在业务逻辑中写
new FileLogger()或new DBLogger() - 接口要聚焦行为契约(如
log(String msg)),不暴露构造参数或内部状态 - 具体类负责自身初始化逻辑,例如连接数据库、打开文件句柄等
把创建决策交给子类工厂
声明一个抽象工厂类,只定义创建方法(如 createLogger()),但不实现;每个具体工厂子类覆盖该方法,返回对应的具体产品实例。
- FileLoggerFactory 返回 FileLogger
- DBLoggerFactory 返回 DBLogger
- 客户端只依赖抽象工厂,运行时由配置、策略或上下文决定用哪个子类
- 新增 CloudLogger 时,只需加 CloudLogger 类 + CloudLoggerFactory 类,不改已有工厂或客户端
用配置或策略驱动工厂选择
实际项目中,通常不会手动 new 工厂子类,而是通过外部配置(如 properties、YAML)或运行时策略(如用户角色、环境变量)来决定使用哪个工厂。
- 读取配置项
logger.type=file,反射加载 FileLoggerFactory - Spring 等框架可通过
@Qualifier或 profile 自动注入对应工厂 bean - 避免在主流程里写 if-else 判断类型再选工厂——那又回到了紧耦合
处理复杂构造参数与依赖注入
当对象创建涉及多参数、可选配置或依赖其他服务时,工厂子类可封装这些细节:
- FileLoggerFactory 内部可读取路径配置、设置缓冲区大小、处理权限检查
- DBLoggerFactory 可组装 DataSource、设置事务隔离级别、预热连接池
- 若依赖已由 DI 容器管理(如 Spring),工厂可接收这些依赖作为构造参数,而非自行 new


















