1. 工厂模式的核心价值与适用场景
第一次接触工厂模式是在2013年参与电商系统重构时,当时商品模块需要支持多种支付方式(支付宝、微信、银联),每种支付接口的初始化参数和调用流程差异很大。如果直接在业务代码中实例化具体支付类,会导致核心业务逻辑与支付实现强耦合——这正是工厂模式要解决的典型问题。
工厂模式属于创建型设计模式,其核心价值在于:
- 将对象创建过程封装在独立的方法或类中
- 客户端代码无需关心具体实现类的构造细节
- 新增产品类型时不影响现有客户端代码
- 统一管理对象的生命周期和创建规则
在以下场景中特别适用:
- 系统需要支持同一接口的多种实现(如不同数据库驱动)
- 对象创建过程复杂或需要统一管理(如连接池)
- 需要动态切换具体实现(如根据配置选择日志存储方式)
- 希望隔离客户端与具体实现类的依赖关系
重要提示:不要为了使用模式而使用模式。当系统中只有一种固定实现,且未来不会扩展时,直接new对象反而是更清晰的选择。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 三种工厂模式的实现与选择
2.1 简单工厂(静态工厂)
这是最基础的实现形式,通过静态方法封装对象创建逻辑:
java复制public class PaymentFactory {
public static Payment createPayment(String type) {
switch(type) {
case "alipay":
return new AlipayPayment();
case "wechat":
return new WechatPayment();
default:
throw new IllegalArgumentException("Unsupported payment type");
}
}
}
优点:
- 代码结构简单直观
- 适合创建逻辑不复杂的场景
缺点:
- 违反开闭原则(新增类型需修改工厂类)
- 静态方法不利于扩展和测试
2.2 工厂方法模式
通过抽象工厂类和具体工厂子类实现:
java复制// 抽象工厂
public interface PaymentFactory {
Payment createPayment();
}
// 具体工厂
public class AlipayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new AlipayPayment();
}
}
典型应用:
- JDK中的Collection.iterator()
- Spring的BeanFactory
- 日志框架的Appender创建
优势:
- 符合开闭原则
- 支持多态和继承
- 便于单元测试
2.3 抽象工厂模式
用于创建相关或依赖对象的家族:
java复制public interface GUIFactory {
Button createButton();
Dialog createDialog();
}
public class WindowsFactory implements GUIFactory {
// 实现Windows风格的控件创建
}
使用场景:
- 跨平台UI组件库
- 数据库访问套件(Connection+Statement)
- 游戏中的场景元素生成
3. 工业级实现的最佳实践
3.1 结合依赖注入
现代框架通常将工厂与DI容器结合:
java复制@Configuration
public class PaymentConfig {
@Bean
@ConditionalOnProperty(name="payment.type", havingValue="alipay")
public Payment alipayPayment() {
return new AlipayPayment();
}
}
3.2 线程安全考虑
对于需要复用对象的场景:
java复制public class ConnectionPool {
private static final Map<String, Connection> pool = new ConcurrentHashMap<>();
public static Connection getConnection(String dbType) {
return pool.computeIfAbsent(dbType, type -> {
// 线程安全的延迟初始化
return createConnection(type);
});
}
}
3.3 性能优化技巧
- 对象缓存:对昂贵对象实施对象池
- 预初始化:系统启动时提前创建常用对象
- 原型模式:通过克隆避免重复构造
4. 典型问题排查指南
4.1 循环依赖问题
症状:工厂A依赖工厂B,工厂B又依赖工厂A
解决方案:
- 引入第三方协调者
- 改用setter注入
- 重构设计消除循环
4.2 初始化异常处理
java复制try {
Payment payment = PaymentFactory.createPayment(config);
} catch (IllegalArgumentException e) {
// 处理不支持的支付类型
} catch (PaymentInitException e) {
// 处理初始化失败
}
4.3 动态扩展方案
通过配置文件实现热更新:
yaml复制# payments.yaml
paymentTypes:
- id: alipay
class: com.example.AlipayPayment
params:
appId: "2021000116691234"
配合反射机制动态加载:
java复制Payment payment = (Payment) Class.forName(className)
.getConstructor(Map.class)
.newInstance(params);
5. 模式演进与替代方案
5.1 Java 8+的函数式工厂
java复制Map<String, Supplier<Payment>> factories = Map.of(
"alipay", AlipayPayment::new,
"wechat", WechatPayment::new
);
Payment payment = factories.get(type).get();
5.2 Spring的工厂Bean
java复制@Bean
@Scope("prototype")
public Payment payment() {
return new AlipayPayment();
}
5.3 建造者模式替代场景
当对象构造需要多个步骤时:
java复制Payment payment = new PaymentBuilder()
.withType("alipay")
.withConfig(config)
.withRetryPolicy(policy)
.build();
在实际架构设计中,我倾向于这样选择:
- 简单逻辑 → 静态工厂
- 多态需求 → 工厂方法
- 产品家族 → 抽象工厂
- 复杂构造 → 建造者+工厂组合
最后分享一个真实案例:在微服务架构中,我们使用工厂模式动态创建Feign客户端,根据服务元数据自动配置超时、重试等参数。这套机制支撑了公司200+微服务的高效调用,日均处理请求超5亿次。关键点在于工厂类不仅负责创建,还维护了客户端缓存和健康状态检查。
