工厂模式是Java中常用的创建型设计模式,核心思想是将对象的创建过程封装起来,让调用方不需要直接依赖具体实现类,而是通过工厂获取对象实例,从而实现接口与实现类的解耦。这种解耦方式能有效降低代码的耦合度,提升系统的可维护性和扩展性。

工厂模式的核心概念
工厂模式主要分为简单工厂模式、工厂方法模式和抽象工厂模式三种类型,三者的核心目标都是封装对象创建逻辑。其中简单工厂模式通过一个工厂类根据传入的参数决定创建哪种具体产品实例,是最基础的实现形式。
接口在Java中定义了规范,具体实现类负责实现接口中定义的方法。在没有工厂模式的情况下,调用方需要直接通过new关键字创建具体实现类的实例,这就导致调用方直接依赖了具体实现类,一旦实现类发生变更,调用方的代码也需要同步修改。
工厂模式如何实现接口解耦
工厂模式通过引入工厂类作为中间层,将对象创建的逻辑从调用方转移到工厂类中。调用方只需要依赖接口和工厂类,不需要知道具体实现类的存在,这样就实现了接口与实现类的解耦。下面通过简单工厂模式的示例来展示具体实现。
定义接口与实现类
首先定义一个支付接口,以及两个具体的支付实现类:
// 支付接口
public interface Payment {
void pay(double amount);
}
// 支付宝支付实现类
public class AliPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付,金额:" + amount + "元");
}
}
// 微信支付实现类
public class WeChatPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用微信支付,金额:" + amount + "元");
}
}
创建简单工厂类
接下来创建支付工厂类,封装对象创建的逻辑:
public class PaymentFactory {
// 根据支付类型创建对应的支付实例
public static Payment createPayment(String payType) {
if ("alipay".equals(payType)) {
return new AliPay();
} else if ("wechat".equals(payType)) {
return new WeChatPay();
} else {
throw new IllegalArgumentException("不支持的支付类型");
}
}
}
调用方使用工厂获取实例
调用方不需要直接创建具体实现类的实例,只需要通过工厂获取接口实例即可:
public class OrderService {
public void processOrder(String payType, double amount) {
// 通过工厂获取Payment实例,调用方只依赖Payment接口
Payment payment = PaymentFactory.createPayment(payType);
payment.pay(amount);
}
public static void main(String[] args) {
OrderService orderService = new OrderService();
orderService.processOrder("alipay", 100.0);
orderService.processOrder("wechat", 200.0);
}
}
解耦效果分析
在上述示例中,OrderService作为调用方,只依赖了Payment接口和PaymentFactory工厂类,完全没有依赖AliPay和WeChatPay这两个具体实现类。如果后续需要新增银联支付方式,只需要新增UnionPay实现类,然后在工厂类中添加对应的创建逻辑即可,OrderService的代码不需要做任何修改。
这种解耦方式带来的好处是显而易见的:当具体实现类发生变更或者新增实现类时,调用方的代码不需要改动,只需要调整工厂类的逻辑,大大降低了代码的维护成本。同时如果后续需要替换工厂的实现,比如从简单工厂升级为工厂方法模式,调用方的代码也不需要调整,只需要替换工厂类的实现即可。
不同工厂模式的解耦差异
简单工厂模式虽然能实现基本的解耦,但工厂类本身仍然存在一定的耦合,新增产品时需要修改工厂类的判断逻辑。工厂方法模式则是将工厂类抽象为接口,每个具体产品对应一个具体工厂类,新增产品时只需要新增对应的工厂类,不需要修改原有工厂的代码,解耦程度更高。
抽象工厂模式则适用于创建一组相关的产品族,同样是围绕接口展开,通过抽象工厂接口封装一族产品的创建逻辑,让调用方不需要依赖具体产品族的实现类,进一步提升代码的扩展性。
使用注意事项
- 工厂模式适合对象创建逻辑较为复杂的场景,如果对象创建非常简单,直接使用
new关键字反而更清晰,不需要过度设计。 - 接口的定义要合理,尽量保证接口的职责单一,避免接口过于臃肿,否则工厂创建的对象可能会包含很多不需要的方法。
- 工厂类的职责要单一,不要在一个工厂类中封装过多不相关的产品创建逻辑,否则会导致工厂类难以维护。