談談使用責任鏈模式的正確姿勢

責任鏈是很多框架和項目常用的設計模式,可有效保證代碼的可擴展性、複用性、高內聚低耦合,責任鏈模式本身並不複雜,但是很多博客的示例代碼的用法屬於“教科書”式的實踐,不適合在實際軟件工程中的運用,筆者將結合在項目中使用的心得體會,談談使用責任鏈模式的正確姿勢。

在這裏插入圖片描述

一、何謂責任鏈

責任鏈的設計模式其實就是把若干個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);
        }
    }
    
}

更多內容歡迎關注個人微信公衆號,一起成長!

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章