责任链模式你用对了吗

责任链是很多框架和项目常用的设计模式,可有效保证代码的可扩展性、复用性、高内聚低耦合,责任链模式本身并不复杂,但是很多博客的示例代码的用法属于“教科书”式的实践,不适合在实际软件工程中的运用,笔者将结合在项目中使用的心得体会,谈谈使用责任链模式的正确姿势。

一、何谓责任链

责任链的设计模式其实就是把若干个request处理器,以“链”的形式组织起来,“链”是该设计模式的关键和核心问题。
责任链模式可以动态地组织和分配处理器,比较灵活,代码的可扩展性也很好,需要加新的处理器时,直接上链就好。
另外每个处理器都是一个单独的类,这样处理器之间高内聚、低耦合,代码的复用性也比较高。

二、责任链使用的误区

使用责任链的一个误区是通过递归的方式来执行处理器,递归最大的不足就是性能很差,如果责任链过长还可能会发生栈溢出。这就是属于“教科书”式的用法,很多博客的代码上都是这么写的,这是不能用在实际的软件开发中的,性能是其最大的bug。

三、责任链应用的正确姿势

1.要使用好责任链模式,要解决一下几个问题:

  • 以什么样的链来组织处理器

Java中常用的“链”的数据结构是List,比如ArrryList与LinkedList,我们可以使用List数据结构来组织不同的处理器成为一条链。

  • 如何保证处理器之间执行的顺序性

不使用递归,使用for循环来保证责任链执行的顺序性,代码反而更简洁和优雅,且不存在性能问题。

  • 何时加载责任链

一般来说,某个请求的处理器之间的执行顺序是确定,我们可以在bean初始化的时候来完成责任链的组装。InitializingBean#afterPropertiesSet可以用来在处理器都初始化完成后,进行责任链的组装。

2.实例代码

代码主要包括,一个接口,若干实现类、组装和执行类
下面通过一个参数校验责任链的demo来展示责任链的用法。

/**
 * 参数校验接口,这是责任链
 */
public interface ParamCheckService {

    boolean paramCheck(RequestParam param);
}

/**
 * 参数校验接口实现类
 */
@Service("amountCheckService")
public class AmountCheckServiceImpl implements ParamCheckService {

    private Logger logger = LoggerFactory.getLogger(AmountCheckServiceImpl.class);

    @Override
    public boolean paramCheck(RequestParam param) {

        logger.info("执行数量校验处理器");
        return param.getAmount() > 0;
    }
}

/**
 * 参数校验接口实现类
 */
@Service("moneyCheckService")
public class MoneyCheckServiceImpl implements ParamCheckService {

    private org.slf4j.Logger logger = LoggerFactory.getLogger(MoneyCheckServiceImpl.class);

    @Override
    public boolean paramCheck(RequestParam param) {

        logger.info("执行金额校验处理器");
        BigDecimal money = param.getMoney();
        if (money.compareTo(new BigDecimal(0)) < 0) {
            return false;
        }
        return true;
    }
}

/**
 * 责任链的组装与执行类
 */
@Service
public class ParamCheckChain implements InitializingBean {

    @Autowired
    private ParamCheckService moneyCheckService;

    @Autowired
    private ParamCheckService amountCheckService;

    /**
     * 通过ArrayList,把处理器组织成链
     */
    private List<ParamCheckService> checkChain = new ArrayList<>();

    /**
     * 对象初始化时进行责任链的组装,afterPropertiesSet会在处理器注入完成后执行
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {

        //此处的添加顺序即是责任链的执行顺序
        checkChain.add(moneyCheckService);
        checkChain.add(amountCheckService);

    }

    /**
     * 责任链执行方法,通过for循环来顺序执行处理器
     * @param param
     * @return
     */
    public void chainExcute(RequestParam param) {

        for (ParamCheckService checkService : checkChain) {
            checkService.paramCheck(param);
        }
    }
    
}

更多内容欢迎关注个人微信公众号,一起成长!

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值