在编码过程中你是否经常会遇到过多的 if else ,虽然这样子写逻辑会很清晰,但是一旦条件增多,就会显得代码很臃肿,分支比较多,而且不好维护。这种情况肯定是不建议用if-else的,即使一开始为了加快进度,后面维护起来反而会降低效率。
我们先来看看这堆翔一样的if-else分支
public void pay(String type,String order) {
if (type.equals("wechatPay")) {
wechatPay(order);
} else if (type.equals("ailiPay")) {
ailiPay(order);
} else if (type.equals("googlePay")) {
googlePay(order);
} else {
normalPay(order)
}
}
如果某天新增了一种支付方式,你就需要重新添加一个if else ,日积月累,这段代码到时候就变成了传说中人见人厌的“屎山”。
如果不想维护这种代码,就需要引入策略模式来消除无穷的if else逻辑
策略模式
定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。
策略模式基于的一种开闭原则
开闭原则:
对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。
对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。
使用策略模式重构
首先定义一个接口
public interface payStrategy{
int pay(String order)
}
然后再创建上述的四种策略实现类实现接口
public class WechatPay implements payStrategy{
public int pay (String orderNo) {
....
}
public class ailiPay implements payStrategy{
public int pay (String orderNo) {
....
}
public class googlePay implements payStrategy{
public int pay (String orderNo) {
....
}
public class normalPay implements payStrategy{
public int pay (String orderNo) {
....
}
看到这里你可能还有疑惑,我不知道什么时候调用那个方法啊?还是需要if 或者switch 来判
断啊?
对的,到这一步还没有完全改造完成,这个时候我们就需要引入渠道码,通过我们自定的渠道码,动态获取到具体的实现类这样就可以实现不需要if else判断。怎么通过渠道码获取实现类呢?
工厂模式
public class PayFactory {
enum PayType {
WECHATPAY("wechatPay", "微信支付"),
ALIPAY("aliPay", "阿里支付"),
GOOGOLEPAY("googlepay", "谷歌支付");
ONRMALPAY("normalPay", "通用支付");
// 场景对应的编码
private String code;
// 业务场景描述
private String desc;
ShareType(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String getCode() {
return code;
}
// 省略 get set 方法
}
// 定义策略map缓存
private static final Map<String, PayStrategy> payStrategies = new HashMap<>();
static {
payStrategies.put("wechatPay", new WechatPay ());
payStrategies.put("aliPay", new ailiPay ());
payStrategies.put("googlepay", new googlePay ());
payStrategies.put("normalPay", new normalPay ());
}
// 获取指定策略
public static MockPayStrategy getPayStrategy(String type) {
if (type == null || type.isEmpty()) {
throw new IllegalArgumentException("type should not be empty.");
}
return payStrategies.get(type);
}
}
到这里改造就基本完成了,代码在消除了if- else 的堆叠之后,是不是清爽了很多
总结
假设需要接入新的支付方式,采用策略模式+工厂模式,就不需要再使用else if 去判断。现在只需要在枚举中定义一个新的枚举对象,然后再增加一个策略实现类,实现对应方法的逻辑,就可以很轻松地扩展。也实现了开闭原则。