需求
系统对接多种第三方支付方式(第三方登录)对于同一功能场景有多种策略时;在此拿支付举例(支付宝、微信).
基本代码
支付类型枚举
public enum PayTypeEnum {
ALI_PAY("ALI_PAY","支付宝支付"),
WX_PAY("WX_PAY","微信支付"),
;
public static PayTypeEnum getByCode(String code){
for (PayTypeEnum value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
private String code;
private String desc;
PayTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
支付接口定义
public interface PayService {
void pay();
}
if-else实现
支付宝支付
@Service
public class AliPayStrategy implements PayService{
@Override
public void pay() {
System.out.println("阿里支付");
}
}
微信支付
@Service
public class WxPayStrategy implements PayService {
@Override
public void pay() {
System.out.println("微信支付");
}
}
接口
@RequestMapping("/payV1")
public void payV1(@RequestParam String type){
PayService payService = null;
if (PayTypeEnum.ALI_PAY.getCode().equals(type)) {
payService = new AliPayStrategy();
}else if(PayTypeEnum.WX_PAY.equals(type)){
payService = new WxPayStrategy();
}else {
throw new RuntimeException("same exception");
}
payService.pay();
}
策略+工厂
工厂类
@Slf4j
public class PayStrategyFactory {
public static Map<PayTypeEnum, PayService> payTypeEnumPayServiceMap = new EnumMap<>(PayTypeEnum.class);
public static PayService get(String type){
PayService payService = payTypeEnumPayServiceMap.get(PayTypeEnum.getByCode(type));
if (payService==null) {
throw new RuntimeException("paystrategy not register");
}
return payService;
}
public static void register(PayTypeEnum payTypeEnum,PayService service){
PayService payService = PayStrategyFactory.payTypeEnumPayServiceMap.get(payTypeEnum);
if (payService==null) {
log.info(payTypeEnum.getCode()+" strategy register success");
PayStrategyFactory.payTypeEnumPayServiceMap.put(payTypeEnum,service);
return;
}
throw new RuntimeException(payTypeEnum.getCode() +"strategy register repeat");
}
}
策略类改造
@Service
public class AliPayStrategy implements PayService, InitializingBean {
@Override
public void pay() {
System.out.println("阿里支付");
}
@Override
public void afterPropertiesSet() throws Exception {
PayStrategyFactory.register(PayTypeEnum.ALI_PAY,this);
}
}
@Service
public class WxPayStrategy implements PayService, InitializingBean {
@Override
public void pay() {
System.out.println("微信支付");
}
@Override
public void afterPropertiesSet() throws Exception {
PayStrategyFactory.register(PayTypeEnum.WX_PAY,this);
}
}
实现InitializingBean接口,每当策略类被spring
容器启动初始化后会调用afterPropertiesSet
方法来注入到策略工厂
接口
@RequestMapping("/payV2")
public void payV2(@RequestParam String type){
PayStrategyFactory.get(type).pay();
}
启动日志