支付业务设计模式优化嵌套if else


背景

最近在做项目的时候,需要接入支付。由于接入第三方支付而且还不知止一家,需要接入很多家。比如说支付宝、微信、富友支付等。每家支付都一个回调。现如今的代码,根据不同的第三方支付一大堆else if判断。现如今代码如下:

 public PayResponse pay(PayRequestType payRequestType) {
        PayTypeEnum payType = PayTypeEnum.para(payRequestType.getPayType());
        if (payType == PayTypeEnum.ALIPAY) {
            return alipayService.pay(payRequestType);
        } else if (payType == PayTypeEnum.WEIXIN) {
            return weixinPayService.pay(payRequestType);
        } else if (payType == PayTypeEnum.LIANLIAN) {
            return lianlianPayService.pay(payRequestType);
        }
        // 其他支付方式
        return null;
    }

如果以后要接入其他的支付方式,然后就要接着else if 往下写,如果十几家怎么办?所以这个要进行优化。

优化步骤

  1. 创建一个支付接口,提供两个方法
public interface Pay {

    PayResponse pay(PayRequestType payRequestType);

    /**
     * 每家支付方式对应的类型
     * @return
     */
    PayTypeEnum getPayType();
}

每家支付都去实现这个类:比如微信支付

@Component
public class WeixinPayService implements Pay {
    @Override
    public PayResponse pay(PayRequestType payRequestType) {
        return null;
    }

    @Override
    public PayTypeEnum getPayType() {
        return PayTypeEnum.WEIXIN;
    }
  1. 然后准备一个工厂把那些判断if else 消除掉
public final class PayFactory {
    private PayFactory() {
    }
    public static Map<PayTypeEnum, Pay> PAYMAP = new ConcurrentHashMap();
    static {
        Map<String, Pay> beansOfType = ApplicationContextHelper.getBeansOfType(Pay.class);
        for (Map.Entry<String, Pay> entry : beansOfType.entrySet()) {
            Pay pay = entry.getValue();
            PAYMAP.put(pay.getPayType(), pay);
        }
    }

    public static Pay getPay(PayTypeEnum payTypeEnum){
        return  PAYMAP.get(payTypeEnum);
    }

spring获取bean帮助类


@Component
public class ApplicationContextHelper implements ApplicationContextAware {

   public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    public static  <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {
        return applicationContext.getBeansOfType(clazz);
    }

优化后代码

类型枚举新增一个枚举转换方法

public enum PayTypeEnum {
    WEIXIN, LIANLIAN, ALIPAY;
  public static PayTypeEnum para(String type){
        for(PayTypeEnum payTypeEnum:PayTypeEnum.values()){
            if(type.equalsIgnoreCase(payTypeEnum.name())){
                return  payTypeEnum;
            }
        }
        return null;
    }
}
  public PayResponse pay2(PayRequestType payRequestType) {
        PayTypeEnum payType = PayTypeEnum.para(payRequestType.getPayType());
       return PayFactory.getPay(payType).pay(payRequestType);
    }

后续新增支付方式的话,只要新增枚举类型、然后实现pay接口就可以了。没有了复杂的if else 判断了。

总结

本文采用了工厂模式和巧用map的形式消除了if else的判断。

结束

  • 由于自己才疏学浅,难免会有纰漏,假如你发现了错误的地方,还望留言给我指出来,我会对其加以修正。
  • 如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。
  • 感谢您的阅读,十分欢迎并感谢您的关注。
    在这里插入图片描述

文章作者: java金融
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 java金融 !
 上一篇
有了它(powermock)再也不担心单元测试不达标了 有了它(powermock)再也不担心单元测试不达标了
为什么要写单元测试 优点:单元测试可以减少bug率,提升代码的质量。还可以通过单元测试来熟悉业务。 公司硬性要求:有些公司可能还会强制要求,每次新增代码、或者变更代码单测覆盖率要达到多少比例才能申请代码合并请求。选择哪个单元测试框架 目前应
2020-09-09
下一篇 
小白入门多线程,看这篇就够了 小白入门多线程,看这篇就够了
什么是线程 说到线程我们应该先了解下什么是进程,下面这个图片大家应该都比较熟悉吧。我们看到的这些单独运行的程序就是一个独立的进程,进程之间是相互独立存在的。我们上面图中的360浏览器、百度云盘等等都是独立的进程。 那么什么是线程呢? 线程(
2020-09-09