关于支付:关于聚合支付方案支付策略模式

8次阅读

共计 6482 个字符,预计需要花费 17 分钟才能阅读完成。

公司最近在做聚合领取的性能,原来领取计划是不同的领取商户不同的业务解决,扩展性极差,且每新增一个业务商户都要独自开发一套领取接口,很显著这违反了 OOP 的思维。
策略模式的组成部分有三局部

环境类 (Context): 用一个 ConcreteStrategy 对象来配置。保护一个对 Strategy 对象的援用。可定义一个接口来让 Strategy 拜访它的数据。
形象策略类 (Strategy): 定义所有反对的算法的公共接口。Context 应用这个接口来调用某 ConcreteStrategy 定义的算法。具体策略类(ConcreteStrategy): 以 Strategy 接口实现某具体算法。
领取形式的组成也有三局部

领取策略接口 (PayStrategy): 定义领取形式
具体领取形式 (H5PayStrategy、WxPayStrategy、依据本人的): 具体的领取算法
领取策略上下文 (PayStrategyContent): 治理所有领取形式的援用,并依据用户抉择援用对应的领取形式。
代码实现(本案例是接的银联领取)
   领取策略接口(PayStrategy)

/**
*@program:traffic-resource
*@description 领取策略接口
*@author:belive
*@create:2020-12-2521:06
**/
publicinterfacePayStrategy{
/**
* 领取接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@param param
*@returnStringjson 字符串
*/
RestRes<String>consumeApply(Stringparam);

/**
* 查问领取后果接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@param param
*@returnStringjson 字符串
*/
RestRes<String>consumeApplyDetail(Stringparam);

/**
* 退款接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@param param
*@returnStringjson 字符串
*/
RestRes<String>refund(Stringparam);

/**
* 查问退款后果接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@param param
*@returnStringjson 字符串
*/
RestRes<String>refundQuery(Stringparam);

/**
* 敞开订单接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@param param
*@returnStringjson 字符串
*/
RestRes<String>depositApply(Stringparam);

具体领取形式(MiniPayStrategy) 本案例就以扫码领取为例

/**
*@program:traffic-resource
*@description
*@author:belive
*@create:2020-12-2521:18
**/
@Slf4j
@Service
publicclassQrCodePayStrategyimplementsPayStrategy{@Value("${unionPay.url.qrcode_get_qrcode}")
privateStringqrcode_get_qrcode;

@Override
publicRestRes<String>consumeApply(Stringbody){RestRes<String>restRes=newRestRes<>();
TransactionHttptransactionHttp=newTransactionHttp();
Stringresult=transactionHttp.send("https://api-mop.chinaums.com/v1/netpay/bills/get-qrcode",body);

JSONObjectresultObj=JSON.parseObject(result);
if("SUCCESS".equals(resultObj.getString("errCode"))){restRes.setMessage("获取领取链接胜利");
restRes.setCode(0);
}else{restRes.setMessage("获取领取链接失败");
restRes.setCode(1000);
}
restRes.setData(result);
Return restRes;
}

@Override
publicRestRes<String>consumeApplyDetail(Stringparam){Return null;}

@Override
publicRestRes<String>refund(Stringparam){Return null;}

@Override
publicRestRes<String>refundQuery(Stringparam){Return null;}

@Override
publicRestRes<String>depositApply(Stringparam){Return null;}
}

领取策略上下文(PayStrategyContent)

/**
*@program:traffic-resource
*@description 领取策略上下文
*@author:belive
*@create:2020-12-2521:19
**/
@Component
publicclassPayStrategyContent{
/** 策略实例汇合 */
        privateConcurrentHashMap<String,PayStrategy>strategyMap=newConcurrentHashMap<>(20);

/**
* 注入策略实例
* 如果应用的是结构器注入,可能会有多个参数注入进来。*
* 如果应用的是 field 反射注入
*
* 如果应用的是 setter 办法注入,那么你将不能将属性设置为 final。*
*@paramstrategyMap
* 留神注入类型要是 Map 根底类型
*/
@Autowired
publicPayStrategyContent(Map<String,PayStrategy>strategyMap){
    // 清空集合数据
    this.strategyMap.clear();
    if(!CollectionUtils.isEmpty(strategyMap)){strategyMap.forEach((beanName,payStrategy)->{if(StringUtils.isEmpty(beanName)||payStrategy==null){return;}
    this.strategyMap.put(beanName.toLowerCase(),payStrategy);
    });
    }
    }

/**
* 抉择领取形式
* 小程序、H5、扫码
*
*@parampaymentEnums
*
*@returnRemoteResult
*/
publicRestRes<String>consumeApply(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);
}
returnthis.strategyMap.get(paymentEnums.getBeanName()).consumeApply(param);
}
/**
* 查问领取后果接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@parampaymentEnums
*
*@returnRemoteResult
*/
publicRestRes<String>consumeApplyDetail(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);
}
returnthis.strategyMap.get(paymentEnums.getBeanName()).consumeApplyDetail(param);
}
/**
* 退款接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@parampaymentEnums
*
*@returnRemoteResult
*/
publicRestRes<String>refund(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);
}
returnthis.strategyMap.get(paymentEnums.getBeanName()).refund(param);
}

/**
* 查问退款后果接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@parampaymentEnums
*
*@returnRemoteResult
*/
publicRestRes<String>refundQuery(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);
}
returnthis.strategyMap.get(paymentEnums.getBeanName()).refundQuery(param);
}

/**
* 敞开订单接口
*1. 小程序领取
*2.h5 领取
*3. 扫码领取
*4.app 领取
*
*@parampaymentEnums
*
*@returnRemoteResult
*/
publicRestRes<String>depositApply(PaymentEnumspaymentEnums,Stringparam){if(CollectionUtils.isEmpty(strategyMap)){thrownewApiException(ErrorCodeEnum.UNION05);
}
returnthis.strategyMap.get(paymentEnums.getBeanName()).depositApply(param);
}

领取形式枚举(PaymentEnums)

    /**
*@program:traffic-resource
* 领取形式枚举对象
*code-> 领取形式别名
*beanName-> 实例的名称
*@author:belive
*@create:2020-12-2521:00
**/
publicenumPaymentEnums{
/** 领取形式 */
H5_PAY("H5_PAY",H5PayStrategy.class.getSimpleName()),
MINI_PAY("MINI_PAY",MiniPayStrategy.class.getSimpleName()),
QR_CODE_PAY("QR_CODE_PAY",QrCodePayStrategy.class.getSimpleName()),
;
/**
* 枚举定义 + 形容
*/
privateStringcode;
privateStringbeanName;

PaymentEnums(Stringcode,StringbeanName){
this.code=code;
this.beanName=StringUtils.isNotEmpty(beanName)?beanName.toLowerCase():null;}
/**
* 依据 code 获取对应的枚举对象
*/
publicstaticPaymentEnumsgetEnum(Stringcode){PaymentEnums[]values=PaymentEnums.values();
if(null!=code&&values.length>0){for(PaymentEnumsvalue:values){if(value.code.equals(code)){returnvalue;}
}
}
returnnull;
}
/**
* 该 code 在枚举列表 code 属性是否存在
*/
publicstaticbooleancontainsCode(Stringcode){PaymentEnumsanEnum=getEnum(code);
returnanEnum!=null;
}
/**
* 判断 code 与枚举中的 code 是否雷同
*/
publicstaticbooleanequals(Stringcode,PaymentEnumscalendarSourceEnum){returncalendarSourceEnum.code.equals(code);
}

publicStringgetCode(){returncode;}
publicStringgetBeanName(){returnbeanName;}
}

自定义 Bean 加载(PayStrategyContentConfig)


/**
*@program: traffic-resource
*@description
*@author: belive
*@create: 2020-12-3023:07
**/
@Configuration
public class PayStrategyContentConfig {
@Bean
 public PayStrategyContent payStrategyContentInit() {H5PayStrategy h5PayStrategy = new H5PayStrategy();
 MiniPayStrategy miniPayStrategy = new MiniPayStrategy();
 QrCodePayStrategy qrCodePayStrategy = new QrCodePayStrategy();
 HashMap<String, PayStrategy> strategyMap = new HashMap<>();
 strategyMap.put(PaymentEnums.H5_PAY.getBeanName(), h5PayStrategy);
 strategyMap.put(PaymentEnums.MINI_PAY.getBeanName(), miniPayStrategy);
 strategyMap.put(PaymentEnums.QR_CODE_PAY.getBeanName(), qrCodePayStrategy);
 PayStrategyContent payStrategyContent = new PayStrategyContent(strategyMap);
 return payStrategyContent;
 }
}

领取相干业务调用(代码片段)

@Resource
privatePayStrategyContentConfigpayStrategyContentConfig;   
RestRes<String>result=payStrategyContentConfig.payStrategyContentInit().consumeApply(PaymentEnums.QR_CODE_PAY,body.toJSONString());
正文完
 0