hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

如安在Spring Boot项目中奇妙应用战略形式干掉if else!

2019-11-18杂谈搜奇网34°c
A+ A-

直入主题

我们都晓得,设想形式(Design Pattern)是先辈们对代码开辟履历的总结,是处置惩罚特定题目的一系列套路。它不是语法划定,而是一套用来进步代码可复用性、可维护性、可读性、妥当性以及安全性的处置惩罚方案。
那末,我们能够都相识过设想形式,但是在项目中怎样运用能够照样会有点迷惑,本日,公司的项目恰好有一个场景来让我运用一个设想形式:战略形式。

场景

关于用户定单充值(定单付出同理),我们都晓得,当今的付出体式格局是异常的多的,比方:付出宝、微信、银联、钱包(各个APP的账户余额)等等。
查询实体Query:

/**
 * @author Howinfun
 * @desc 查询
 * @date 2019/10/22
 */
@Data
public class ChargeQuery {
    
    /** 付出体式格局(ALI/WX/UNION) */
    @NotBlank(message = "付出体式格局不能为空",groups = PayWayNotBlank.class)
    private String payWay;
    
    /** 充值金额 */
    @NotNull(message = "充值金额不能为空",groups = AmountNotNull.class)
    private Double amount;
}

Service接口:

/**
 * @author Howinfun
 * @desc 充电-充值模块
 * @date 2019/10/30
 */
public interface ChargeRechargeService {

    /**
     * 依据不必付出体式格局举行用户余额充值
     * @param query
     * @return
     */
    Result recharge(ChargeQuery query);

    /**
     * 充值回调
     * @param rechargeCallBack
     */
    Result rechargeCallBack(RechargeCallBack rechargeCallBack);
}

传统体式格局完成

就是应用if else或许switch来举行前提推断:

/**
 * @author Howinfun
 * @desc
 * @date 2019/10/30
 */
@Service
@AllArgsConstructor
@Slf4j
public class ChargeRechargeServiceImpl implements ChargeRechargeService {

    private final CarUserMapper carUserMapper;
    private final IncomePaymentMapper incomePaymentMapper;
    private final RechargeRecordMapper rechargeRecordMapper;
    private final PayWayHandlerContext payWayHandlerContext;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result recharge(ChargeQuery query) {
        Result result = new Result();
        // ......
        // ......
        if (PayConstant.PAY_WAY_WX.equals(query.getPayWay())){
            // 微信
            // ......
        }else if (PayConstant.PAY_WAY_ALI.equals(query.getPayWay())){
            // 付出宝
            // ......

        }else if (PayConstant.PAY_WAY_UNION_PAY.equals(query.getPayWay())){
             // 银联
             // ......
    
        }
        return result;
    }
}

总结:我们能够看到,传统的完成体式格局是异常的笨重的,而且代码异常的不简约,扩展性差。假如我们要接入新的付出体式格局,那末我们只能继续增加 else if。

战略形式

Talk is cheap,show me the code.
我们先看一下,假如运用战略形式,service的代码将变成啥样。

/**
 * @author Howinfun
 * @desc
 * @date 2019/10/30
 */
@Service
@AllArgsConstructor
@Slf4j
public class ChargeRechargeServiceImpl implements ChargeRechargeService {

    private final PayWayHandlerContext payWayHandlerContext;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result recharge(ChargeQuery query) {
        return this.payWayHandlerContext.getHandlerInstance(query.getPayWay()).handler(query);
    }
}

emmmm,确实是简朴了不少。不只代码量少了,简约了,而且不再忧郁由于新增付出体式格局而修正serviceImpl的代码了。

下面举行细致的解说:
1、起首,我们须要自定义一个注解,来标识一个付出范例对应的一个处置惩罚器。

/**
 * @author Howinfun
 * @desc 自定义注解,标识付出范例
 * @date 2019/11/2
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface PayWayHandler {

    String value();
}

2、接着,笼统一个处置惩罚器,让每一个付出体式格局的处置惩罚器继续此笼统处置惩罚器,完成handle要领:

/**
 * @author Howinfun
 * @desc 笼统定单范例处置惩罚器
 * @date 2019/11/2
 */
public abstract class AbstractPayWayHandler {

    /**
     *
     * @param query
     * @return
     */
    abstract public Result handler(ChargeQuery query);
}

3、完成类,比方付出宝、微信、银联:
注重:每一个处置惩罚器都要加上@component,交给Spring治理。

/**
 * @author Howinfun
 * @desc 付出宝付出
 * @date 2019/11/2
 */
@Component
@PayWayHandler("ALI")
@Slf4j
@AllArgsConstructor
public class AliPayWayHandler extends AbstractPayWayHandler {
    
    // ....种种依靠

    @Override
    public Result handler(ChargeQuery query) {
        Result result = new Result();
        // ......
        return result;
    }
}

/**
 * @author Howinfun
 * @desc 微信付出
 * @date 2019/11/2
 */
@Component
@PayWayHandler("WX")
@Slf4j
@AllArgsConstructor
public class WxPayWayHandler extends AbstractPayWayHandler {
    
    // ....种种依靠

    @Override
    public Result handler(ChargeQuery query) {
        Result result = new Result();
        // ......
        return result;
    }
}

/**
 * @author Howinfun
 * @desc 银联付出
 * @date 2019/11/2
 */
@Component
@PayWayHandler("UNION")
@Slf4j
@AllArgsConstructor
public class UnionPayWayHandler extends AbstractPayWayHandler {
    
    // ....种种依靠

    @Override
    public Result handler(ChargeQuery query) {
        Result result = new Result();
        // ......
        return result;
    }
}

4、然后最重点的来了,建立一个类,完成ApplicationContextAware接口,重写setApplicationContext要领,然后扫描带有自定义注解@PayWayHandler的Bean,然后存储起来,轻易Service的猎取。

/**
 * @author Howinfun
 * @desc
 * @date 2019/11/2
 */
@Component
public class PayWayHandlerContext implements ApplicationContextAware {

    @Autowired ApplicationContext applicationContext;

    /** key为PayWay,value为class*/
    private static final Map<String,Class> handlerMap = new HashMap<>(10);

    public AbstractPayWayHandler getHandlerInstance(String payType){
        Class clazz = handlerMap.get(payType);
        if (clazz == null){
            throw new CustomDeniedException("暂不支撑此付出体式格局");
        }
        return (AbstractPayWayHandler) applicationContext.getBean(clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 遍历带有PayTypeHandler解释的类
        Map<String,Object> beans = applicationContext.getBeansWithAnnotation(PayWayHandler.class);
        if (beans != null && beans.size() > 0) {
            for (Object serviceBean : beans.values()) {
                String payType = serviceBean.getClass().getAnnotation(PayWayHandler.class).value();
                handlerMap.put(payType, serviceBean.getClass());
            }
        }
    }
}

总结:到此,ServiceImpl可依据前端传过来的payWay来挑选对应的handler来处置惩罚。我应用了战略形式简化了冗杂的 if else 代码,而且扩展性得到了大大的提拔,不再忧郁由于付出体式格局的新增而修正营业代码。

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
如安在Spring Boot项目中奇妙应用战略形式干掉if else!

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282141.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>