我有话要讲
通常我们在一些有较多判断逻辑的业务中,都是写一大串的if-else,比如说在提交订单选择支付方式的时候,一般会有三个选项:支付宝、微信和账户余额支付。然后就会出现这样的代码👇
if(PayTypeEnum.ALIPAY.equals(typeEnum)) {
// ......
return "支付宝支付";
} else if(PayTypeEnum.WECHAT.equals(typeEnum)) {
// ......
return "微信支付";
} else {
// ......
return "账户余额支付";
}
这时候就有朋友问了:“我寻思着,我这样写也妹啥问题呀?”
emmm…确实没问题,但是不够优雅,各种实现方式堆积在一起,其他同学看了直呼头皮发麻。高端的程序boy怎么能够没点追求呢
“那么,啥样儿才算优雅呢?”
好的朋友,接下来我们就用“优雅”的设计模式–策略模式来改造一下
策略模式
首先我们先定义一下支付类型的枚举,用于接口中传递类型参数及类型传参验证
public enum PayTypeEnum {
/**
* 支付宝支付
*/
ALIPAY("支付宝支付"),
/**
* 微信支付
*/
WECHAT("微信支付"),
/**
* 余额支付
*/
ACCOUNT("余额支付");
private String value;
PayTypeEnum(String value) {
this.value = value;
}
}
然后我们将支付这一操作抽象出来,不论你是支付宝,还是微信,又或者是余额支付,都属于支付行为,那么我们可以将支付行为当作一个抽象方法,由它的实现类去实现这个行为,来完成具体的支付操作
public interface IPay {
/**
* 支付的抽象方法
* @return 支付响应
*/
String pay();
}
public class AliPay implements IPay {
@Override
public String pay() {
return "支付宝支付";
}
}
public class WeChatPay implements IPay {
@Override
public String pay() {
return "微信支付";
}
}
public class AccountPay implements IPay {
@Override
public String pay() {
return "账户余额支付";
}
}
到这里,策略模式就改造完成,调用的时候我们可以根据不同的支付类型new具体的实现类对象,即可完成对应类型的支付方法调用
public String orderPay(String payType) {
PayTypeEnum typeEnum;
try {
typeEnum = PayTypeEnum.valueOf(payType.toUpperCase());
} catch (Exception e) {
return "未知支付方式";
}
if(PayTypeEnum.ALIPAY.equals(typeEnum)) {
return new AliPay().pay();
} else if(PayTypeEnum.WECHAT.equals(typeEnum)) {
return new WeChatPay().pay();
} else {
return new AccountPay().pay();
}
}
这时候又有朋友问了:“欸?不对!我寻思着,你这不还是if-else嘛?”
害,别着急呀。刚刚我们只是将支付逻辑抽取出来,而接下来我们要做的,就是用工厂模式将判断逻辑优化一下
工厂模式
这时候我们需要定义一个支付工厂,在这个工厂里面,我们通过构造方法,将之前定义好的三种支付方式实现类加入Map中,Map的key就是支付类型,而value则是支付方法的实现类。这样一来我们就可以在getPay()方法中,通过支付类型的枚举,来匹配Map中的key,得到具体的支付实现
@Component
public class PayFactory {
private final HashMap<String, IPay> payHashMap;
public PayFactory() {
payHashMap = new HashMap<>(3);
payHashMap.put(PayTypeEnum.ALIPAY.toString(), new AliPay());
payHashMap.put(PayTypeEnum.WECHAT.toString(), new WeChatPay());
payHashMap.put(PayTypeEnum.ACCOUNT.toString(), new AccountPay());
}
public IPay getPay(PayTypeEnum payType) {
return payHashMap.get(payType.toString());
}
}
现在我们的支付调用方式就如下所示
@Autowired
private PayFactory payFactory;
@Override
public String orderPay(String payType) {
PayTypeEnum typeEnum;
try {
typeEnum = PayTypeEnum.valueOf(payType.toUpperCase());
} catch (Exception e) {
return "未知支付方式";
}
return payFactory.getPay(typeEnum).pay();
}
这里使用到了策略模式和工厂模式,将支付逻辑与类型判断抽离解耦,在业务逻辑中,无需考虑如何去实现对应的支付操作,仅仅只是一个支付方法的调用即可,而具体的支付行为,都在一个个实现类中,如果还需增加一个支付类型的话,只需要添加一个支付类型的枚举和支付实现类,然后在支付工厂中加入到Map就完事儿了。
以上就是本次改造的全部内容。