问题场景:
订阅 Paypal 付款成功的 webhook 后,每次只会异步通知同一个方法,当需要在支付货款、运费成功后,需要执行不同的业务逻辑时,则可能出现下面的代码
if (paymentType == PaymentTypeEnum.ORDER) {
...
} else if (paymentType == PaymentTypeEnum.FREIGHT) {
...
}
后续每增加一种支付方式,就需要加个 else if ,长久以往,代码维护性较差。
解决思路
使用策略模式,先定义对应的策略,再根据回调时传入不同的支付方式,执行对应的业务逻辑。
代码实现
1、先定义一个支付成功接口
public interface PaypalStrategy {
/**
* 支付策略
*/
boolean paySuccess(String order);
}
2、定义一个支付成功的策略
public class DefaultPaypalStrategyImpl implements PaypalStrategy{
@Override
public boolean paySuccess(String order) {
// 实现支付成功的逻辑
System.out.println("======本次支付订单号:"+order+"==================");
return true;
}
}
3、定义一个枚举
/**
* paypal 支付策略枚举
*
* 要添加新的支付策略 ,可以在这里先定义一个 枚举类型
* eg:DEFAULT(1)
*
*/
public enum PaypalStrategyEnum {
// 默认实现
DEFAULT("DEFAULT"),
// 支付货款
PAY_ORDER("PAY_ORDER"),
// 支付运费
PAY_FREIGHT("PAY_FREIGHT");
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
PaypalStrategyEnum(String code) {
this.code = code;
}
}
3、定义一个策略容器
public class PaypalContext {
// 用一个Map作为容器储存各个支付策略的类,以枚举为参数取出
private static final Map<String, PaypalStrategy> paypalStrategyMap = new ConcurrentHashMap<>();
// 静态块用于初始化各个支付策略实例
static {
// 在这里添加一个策略 key:对应策略枚举code, value:对应的策略实现类
paypalStrategyMap.put(PaypalStrategyEnum.DEFAULT.getCode(), new DefaultPaypalStrategyImpl());
// paypalStrategyMap.put(PaypalStrategyEnum.PAY_ORDER.getCode(), new DefaultPaypalStrategyImpl());
// paypalStrategyMap.put(PaypalStrategyEnum.PAY_FREIGHT.getCode(), new DefaultPaypalStrategyImpl());
}
/**
* 执行策略
* @param orderCode 订单号
* @param strategy 支付策略
* @return
*/
public static boolean executeStrategy(String orderCode, String strategy) {
// 获取策略
PaypalStrategy paypalStrategy = paypalStrategyMap.get(strategy);
// 具体策略执行
return paypalStrategy.paySuccess(orderCode);
}
}
那么 原先回调函数中的 支付成功方法 ,就可以改写成执行容器中的方法
后续需要新增策略,只需三个步骤
1、实现 策略接口 PaypalStrategy ,重写 支付成功 方法,定义自己的业务逻辑
2、在枚举类 添加 一个支付类型
3、在容器中的静态代码块初始化策略
/**
* 支付成功后需要执行的业务逻辑,单独抽取出来
*/
public boolean paySuccess(String orderCode, String paymentType) {
// if (paymentType == PaymentTypeEnum.ORDER) {
// ...
// } else if (paymentType == PaymentTypeEnum.FREIGHT) {
// ...
// }
//执行业务 ,这里会根据 paymentType 找到合适的策略执行任务,eg:支付货款、支付运费等...
return PaypalContext.executeStrategy(orderCode, paymentType);
}