1. 为什么需要工厂
当业务代码直接使用 new 创建具体对象时,调用方会同时依赖对象的接口和实现。实现类型一多,创建参数、选择规则与调用逻辑就会混在一起。工厂模式把“创建哪个对象、怎样创建”集中到独立组件中,让调用方只面向稳定的抽象。
适合使用工厂的场景包括:
- 需要根据配置、类型或运行环境创建不同实现;
- 对象创建过程复杂,需要统一校验、组装依赖或复用实例;
- 希望新增实现时尽量减少对调用方的修改。
如果系统始终只有一个简单实现,直接构造通常更清晰,不必为了模式而增加间接层。
2. 简单工厂
下面以消息通知为例。调用方只依赖 Notifier,由工厂根据类型选择实现。
public interface Notifier { void send(String message);}
public final class EmailNotifier implements Notifier { @Override public void send(String message) { System.out.println("Email: " + message); }}
public final class SmsNotifier implements Notifier { @Override public void send(String message) { System.out.println("SMS: " + message); }}
public final class NotifierFactory { private NotifierFactory() {}
public static Notifier create(String type) { return switch (type.toLowerCase()) { case "email" -> new EmailNotifier(); case "sms" -> new SmsNotifier(); default -> throw new IllegalArgumentException("Unsupported notifier: " + type); }; }}Notifier notifier = NotifierFactory.create("email");notifier.send("构建完成");简单工厂容易理解,也便于集中管理创建规则;它的代价是每增加一种类型通常都要修改工厂中的分支。
3. 工厂方法
当不同产品的创建过程需要独立扩展时,可以把创建动作下放给各自的工厂实现。
public interface NotifierFactory { Notifier create();}
public final class EmailNotifierFactory implements NotifierFactory { @Override public Notifier create() { return new EmailNotifier(); }}
public final class SmsNotifierFactory implements NotifierFactory { @Override public Notifier create() { return new SmsNotifier(); }}调用方可以通过构造参数接收工厂,从而不关心具体产品:
public final class AlertService { private final NotifierFactory factory;
public AlertService(NotifierFactory factory) { this.factory = factory; }
public void alert(String message) { factory.create().send(message); }}4. 如何选择
| 方案 | 适用情况 | 主要代价 |
|---|---|---|
| 直接构造 | 单一、稳定且创建简单 | 调用方依赖具体实现 |
| 简单工厂 | 类型有限,选择规则集中 | 新增类型需要修改分支 |
| 工厂方法 | 产品族持续扩展,创建逻辑各不相同 | 类与接口数量增加 |
核心判断不是“能否使用工厂”,而是对象创建是否已经成为独立的变化点。只有变化值得隔离时,工厂带来的扩展性才大于它增加的复杂度。
评论