本文目录导读:

Java案例深度解析:如何用工厂模式重构你的代码结构?
📖 文章目录
- 什么是工厂模式? – 核心定义与设计意图
- 工厂模式解决的三大痛点 – 为什么你需要它?
- 三种工厂模式实现对比
- 1 简单工厂(静态工厂)
- 2 工厂方法模式
- 3 抽象工厂模式
- Java实战案例:从零构建一个支付工厂
- 常见问题问答(FAQ)
- 性能与SEO建议
什么是工厂模式?
工厂模式(Factory Pattern)是创建型设计模式中最常用的一种,它提供了一种将对象创建逻辑与业务逻辑分离的方式,当你的代码直接使用 new 关键字创建对象时,耦合会变高——而工厂模式让客户端只关心“要什么产品”,不关心“怎么造出来”。
核心思想:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类。
工厂模式解决的三大痛点
- 硬编码耦合:如果业务系统中到处是
new Alipay()、new WeChatPay(),一旦新增支付方式,必须修改所有调用处。 - 扩展困难:不遵循开闭原则(对扩展开放,对修改关闭),每新增一个产品类就要修改原有工厂逻辑。
- 逻辑重复:若每个产品创建前都需要校验、配置或日志,重复代码会急剧膨胀。
一句话总结:工厂模式让你写一次创建逻辑,复用千万次。
三种工厂模式实现对比
1 简单工厂(静态工厂)
特点:使用一个静态方法,根据参数返回不同对象实例。
public class PayFactory {
public static Payment create(String type) {
if ("alipay".equals(type)) return new Alipay();
else if ("wechat".equals(type)) return new WeChatPay();
else throw new IllegalArgumentException("未知支付类型");
}
}
缺点:新增类型必须修改工厂类,违反开闭原则,适合产品数量少且稳定的场景。
2 工厂方法模式
特点:定义一个抽象的工厂接口,每个具体产品对应一个具体工厂。
// 工厂接口
interface PaymentFactory {
Payment create();
}
// 具体工厂
class AlipayFactory implements PaymentFactory {
public Payment create() { return new Alipay(); }
}
class WeChatFactory implements PaymentFactory {
public Payment create() { return new WeChatPay(); }
}
优势:新增类型只需新增具体工厂类,无需修改已有代码。适合单一产品族。
3 抽象工厂模式
特点:创建多个产品族(支付宝的国内支付+国际支付,微信的国内+国际)。
interface AbstractPayFactory {
DomesticPay createDomestic();
InternationalPay createInternational();
}
适用场景:产品等级结构复杂,且产品族之间具有约束关系。
Java实战案例:从零构建一个支付工厂
我们将设计一个 多渠道支付系统,要求:支持支付宝、微信支付、银联支付;未来可能增加Apple Pay;每种支付方式创建时需记录日志和验证密钥。
步骤1:定义产品接口
public interface Payment {
void pay(BigDecimal amount);
void refund(String orderId);
}
步骤2:实现具体产品类
public class Alipay implements Payment {
@Override
public void pay(BigDecimal amount) {
// 调用支付宝API
System.out.println("支付宝支付:" + amount + " 元");
}
@Override
public void refund(String orderId) {
System.out.println("支付宝退款订单:" + orderId);
}
}
// 同理实现 WeChatPay、UnionPay...
步骤3:构建工厂方法模式(推荐方案)
// 抽象工厂
public interface PaymentFactory {
Payment create();
}
// 具体工厂
public class AlipayFactory implements PaymentFactory {
@Override
public Payment create() {
System.out.println("[日志] 创建支付宝支付实例");
validateKey("alipay");
return new Alipay();
}
private void validateKey(String channel) {
// 密钥校验逻辑
}
}
步骤4:客户端使用
public class PaymentClient {
public static void main(String[] args) {
PaymentFactory factory = new AlipayFactory();
Payment payment = factory.create();
payment.pay(new BigDecimal("199.00"));
}
}
效果:若新增 ApplePay,只需写 ApplePay 类和 ApplePayFactory 类,客户端只需选择不同的工厂即可——零侵入。
常见问题问答(FAQ)
❓ Q1:工厂模式一定比直接 new 好吗?
答:不一定,如果你的对象创建逻辑极其简单(String 或 Integer),不需要额外配置或校验,直接 new 更清晰,工厂模式适合创建过程复杂或可能频繁扩展的场景。
❓ Q2:简单工厂和工厂方法怎么选?
答:当产品类型少于5种且变化频率低时,用简单工厂(代码少),当项目需要长期维护、可能频繁新增产品时,用工厂方法(符合开闭原则)。
❓ Q3:抽象工厂和工厂方法的区别?
答:工厂方法生产单一产品;抽象工厂生产多个关联产品族(例如同时生产CPU和主板),如果你的支付系统同时需要国内支付和国际支付两个维度的组合,就用抽象工厂。
❓ Q4:Spring框架中哪里用了工厂模式?
答:Spring的 BeanFactory 和 ApplicationContext 本身就是工厂模式的优秀实现,你可以通过 getBean() 方法获取对象,而无需关心其创建细节和生命周期。
❓ Q5:工厂模式会带来性能问题吗?
答:不会,工厂模式只是封装了创建逻辑,没有引入额外的运行时开销(除非你用反射),Spring中的对象创建默认是单例池复用,性能甚至优于反复 new。
性能与SEO建议
- 搜索引擎友好:本文使用了清晰的标题层级(H1/H2/H3)、列表项和加粗要点,利于爬虫抓取,实际部署时可在
<meta description>中强调“Java工厂模式实现方法”和“支付系统案例”。 - 场景关键词:在正文中自然融入“Java设计模式”“工厂模式案例”“Spring BeanFactory”等长尾词。
- 代码可读性:代码块中加入了中文注释,帮助读者快速理解,建议在GitHub仓库中提供完整Demo,并在文章底部嵌入链接,提升文章权威度。
延伸阅读:当你的系统需要动态加载类或绕过编译时依赖时,可进一步研究 反射工厂模式 和 注册工厂模式,祝你写出低耦合、高内聚的优雅代码!