登录
注册
写文章
发现
工具
基于工厂模式和策略模式设计支付系统
_3t3lfz KEKfID
编辑文章
基于工厂模式和策略模式设计支付系统
asfx站长
2023.08.16 15:12:45
阅读
1378
##背景 支付系统要对接各种第三方支付,根据不同的支付渠道判断拿到对应实现类的方式让代码看起来太恶心了,太多的if else了,并且以后每次对接一个新的支付渠道,都得加判断,不符合开闭原则(模块应该对扩展开放,对修改关闭)。 #解决方案 基于工厂模式和策略模式设计支付系统,让代码简洁优雅,易于维护和扩展。这样每次新加一种支付渠道,都只需新增一个类去实现支付策略接口即可。 ##代码示例 1.定义支付请求对象 ``` /** * @Description: 支付请求对象 * @Author: whm * @CreateTime: 2023-08-16 10:44 * @Version: 1.0 */ @Getter @Setter public class PayVO { /** 交易金额,分 */ private Long amount; /** 支付渠道 */ private String payChannel; } ``` 2.定义支付响应对象 ``` /** * @Description: 支付响应对象 * @Author: whm * @CreateTime: 2023-08-16 10:46 * @Version: 1.0 */ @Getter @Setter public class PayDTO { /** 支付渠道 */ private String payChannel; /** 交易时间 */ private Date transDatetime; /** 交易状态 */ private String transStatus; /** 描述 */ private String desc; @Override public String toString() { return "PayDTO{" + "payChannel='" + payChannel + '\'' + ", transDatetime=" + transDatetime + ", transStatus='" + transStatus + '\'' + ", desc='" + desc + '\'' + '}'; } } ``` 3.定义支付策略接口 ``` /** * @Description: 支付策略(抽象公共的支付功能) * @Author: whm * @CreateTime: 2023-08-16 10:45 * @Version: 1.0 */ public interface PayStrategy { /** * 支付渠道 * @return */ String payChannel(); /** * 统一下单 * @param payVO * @return */ PayDTO unifiedOrder(PayVO payVO); /** * 退款 * @param payVO * @return */ PayDTO refund(PayVO payVO); // TODO 转账 } ``` 4.支付策略工厂 ``` /** * @Description: 支付策略工厂 * @Author: whm * @CreateTime: 2023-08-16 10:52 * @Version: 1.0 */ @Slf4j @Component public class PayStrategyFactory { /** 支付策略Map */ private static Map<String, PayStrategy> payStrategyMap = new HashMap<>(); /** * 注册支付策略 * @param payChannel * @param payStrategy */ public static void register(String payChannel, PayStrategy payStrategy){ payStrategyMap.put(payChannel, payStrategy); } /** * 获取支付策略 * @param payChannel * @return */ public PayStrategy getPayStrategy(String payChannel){ PayStrategy payStrategy = payStrategyMap.get(payChannel); if(payStrategy == null){ throw new RuntimeException("不支持的支付渠道"); } return payStrategy; } } ``` 5.支付策略注册 ``` /** * @Description: 支付策略注册 * @Author: whm * @CreateTime: 2023-08-16 14:10 * @Version: 1.0 */ @Component public class PayStrategyRegistry implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(bean instanceof PayStrategy){ PayStrategy payStrategy = (PayStrategy) bean; PayStrategyFactory.register(payStrategy.payChannel(), payStrategy); } return bean; } } ``` 6.各种支付渠道实现支付策略 ``` /** * @Description: 支付宝支付功能实现 * @Author: whm * @CreateTime: 2023-08-16 10:52 * @Version: 1.0 */ @Slf4j @Component public class AliPayStrategy implements PayStrategy { @Override public String payChannel() { return "ALIPAY"; } @Override public PayDTO unifiedOrder(PayVO payVO) { PayDTO dto = new PayDTO(); dto.setDesc("ALI unifiedOrder"); return dto; } @Override public PayDTO refund(PayVO payVO) { PayDTO dto = new PayDTO(); dto.setDesc("ALI refund"); return dto; } } ``` ``` /** * @Description: 微信支付功能实现 * @Author: whm * @CreateTime: 2023-08-16 10:54 * @Version: 1.0 */ @Slf4j @Component public class WXPayStrategy implements PayStrategy { @Override public String payChannel() { return "WXPAY"; } @Override public PayDTO unifiedOrder(PayVO payVO) { PayDTO dto = new PayDTO(); dto.setDesc("WX unifiedOrder"); return dto; } @Override public PayDTO refund(PayVO payVO) { PayDTO dto = new PayDTO(); dto.setDesc("WX refund"); return dto; } } ``` 7.测试 ``` @SpringBootTest public class TestPay { @Resource PayStrategyFactory payStrategyFactory; @Test public void unifiedOrder(){ PayVO payVO = new PayVO(); payVO.setPayChannel("ALIPAY"); // payVO.setPayChannel("WXPAY"); PayDTO dto = payStrategyFactory.getPayStrategy(payVO.getPayChannel()).unifiedOrder(payVO); System.out.println(dto); PayDTO dto2 = payStrategyFactory.getPayStrategy(payVO.getPayChannel()).refund(payVO); System.out.println(dto2); } } ``` 输出结果 ```java PayDTO{payChannel='null', transDatetime=null, transStatus='null', desc='ALI unifiedOrder'} PayDTO{payChannel='null', transDatetime=null, transStatus='null', desc='ALI refund'} ```
我的主页
退出