在 Java 开发中,对象的创建是一个常见的场景,如果对象的创建和使用都写在一起,代码的耦合度高,违反单一职责原则。我们可以使用工厂模式来解决这个问题,工厂模式是一个创建型模式,将对象的创建和使用分离开来,降低代码的耦合度,提高程序的可维护性和扩展性。
一、场景
电商平台下单之后,支付需要可以选择不同的支付的方式,比如拼多多下单后,就会有多种支付方式:
- 微信支付
- 支付宝支付
- 多多支付
传统实现方式
传统实现类结构如下:
首先定义一个支付接口,以及几个实现类,比如微信支付,支付宝支付:
// 支付接口
public interface Pay {
void pay();
}
// 支付宝支付
public class AliPay implements Pay{
@Override
public void pay() {
System.out.println("支付宝支付 .....");
}
}
// 微信支付
public class WechatPay implements Pay{
@Override
public void pay() {
System.out.println("微信支付 .....");
}
}
// 多多支付
public class PddPay implements Pay{
@Override
public void pay() {
System.out.println("多多支付 .....");
}
}
一个下单方法里面包含创建订单、支付、更新订单方法,所以代码都冗余到了一起:
public void order(int payType) {
// 创建订单
// 省略代码......
// 根据type 调用不同的支付
Pay pay;
if (payType == 1) {
pay = new AliPay();
} else if(payType == 2){
pay = new WechatPay();
} else if(payType == 3){
pay = new PddPay();
}
// 调用支付
pay.pay();
// 更新状态 代码省略.....
}
以上代码耦合度很高,有以下几个缺点:
- 违反单一职责原则,对象的创建散落在多个地方,没有一个统一的地方处理对象创建,代码耦合度高。
- 代码可读性差,后续阅读代码难度增加。
- 难以扩展和修改,后续添加新的支付方法,或者更修支付方式,需要在多个地方修改代码,增加代码的维护成本。
二、工厂模式应用
简单工厂模式
概述
简单工厂模式通过一个工厂类来决定创建出哪一种产品类的实例。
ER图结构:
应用
将 order 方法的支付代码抽取到工厂类中:
// 支付工厂类
public class PayFactory {
public static Pay getPay(int payType) {
Pay pay;
if (payType == 1) {
pay = new AliPay();
} else if(payType == 2){
pay = new WechatPay();
} else if(payType == 3){
pay = new PddPay();
}
return pay;
}
}
使用工厂模式后,支付直接调用 PayFactory 工厂类,由PayFactory创建需要的支付对象。
public void order2(int payType) {
// 创建订单
// 省略代码......
// 根据type 调用不同的支付
Pay pay = PayFactory.getPay(payType);
// 调用支付
pay.pay();
// 更新状态 代码省略.....
}
优缺点
优点:对象的使用和创建分离,符合单一职责原则。
缺点:如果增加新的具体产品类,需要修改工厂类的代码,不符合开闭原则。
工厂方法模式
概述
工厂方法模式定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
ER图结构:
应用
将创建方法提出来创建一个工厂接口
public interface IPayFactory {
IPay create();
}
创建多个PayFactory工厂
public class WechatPayFactory implements IPayFactory {
@Override
public IPay create() {
return new WechatPay();
}
}
public class AliPayFactory implements IPayFactory {
@Override
public IPay create() {
return new AliPay();
}
}
public class PddPayFactory implements IPayFactory {
@Override
public IPay create() {
return new PddPay();
}
}
优缺点
优点:
- 工厂职责单一化,创建和使用逻辑分离,易于维护;
- 相较于简单工厂模式,新增产品类时无需改动工厂类,符合开闭原则;
缺点:类数量变多。
抽象工厂模式
概述
抽象工厂模式是工厂方法模式的扩展,工厂方法模式只生产单一等级的产品,而抽象工厂模式可以生产多个等级的产品。
优缺点
优点: 相比于工厂方法可以少创建很多类
缺点:
- 首先显而易见的是不符合开闭原则,如果增加一个产品那么冲总工厂到具体实现工厂都要增加对应的方法
- 增加了系统的抽象性和理解难度