責任鏈模式(案例解析)(9)
- 2021 年 10 月 29 日
- 筆記
- 【Java】-- 設計模式
一、概念
1、理解責任鏈模式
責任鏈模式是一種對象的行為模式,責任鏈模式實際上是一種處理請求的模式 它讓多個處理器(對象節點)都有機會處理該請求,請求通過這條加工鏈進行一步步的處理後。輸出最終的產品產出。
2、JDK中的責任鏈模式示例
讓我們看一下JDK中責任鏈模式的例子,然後我們將繼續實現這種模式的真實例子。我們知道在try-catch塊程式碼中我們可以有多個catch塊。這裡每個catch塊都是處理該特定異常的處理器。
因此當try塊中發生任何異常時,它會發送到第一個catch塊進行處理。如果catch塊無法處理它,它會將請求轉發到鏈中的下一個對象,即下一個catch塊。如果即使最後一個catch塊也無法處理它,那麼異常將被拋出鏈接到調用程式。
3、責任鏈模式使用
責任鏈模式怎麼使用呢?
- 一個介面或者抽象類
- 每個對象差異化處理
- 對象鏈(數組)初始化(連起來)
二、舉例演示
我們在項目處理請求的時候,一個請求過來,我們可以進行 1)非空參數檢查 2)安全調用校驗 3)校驗黑名單 4)規則攔截對象 這些就是一個責任鏈。
按照上面的使用說明規則,來建好相應的類,進行演示。
1、一個介面或者抽象類
這個介面或者抽象類,需要:
- 有一個指向責任下一個對象的屬性
- 一個設置下一個對象的set方法
- 給子類對象差異化實現的方法(如以下程式碼的doFilter方法)
/**
* @Description: 定義一個介面或者抽象類
*/
public abstract class AbstractHandler {
/**
* 責任鏈中的下一個對象
*/
private AbstractHandler nextHandler;
// 具體參數攔截邏輯,給子類去實現
public void filter(HttpServletRequest request, HttpServletResponse response) {
//執行當前鏈
doFilter(request, response);
//如果還有下個鏈,執行下個鏈
if (getNextHandler() != null) {
getNextHandler().filter(request, response);
}
}
//獲取下一個鏈對象
public AbstractHandler getNextHandler() {
return nextHandler;
}
//插入責任鏈的下一個對象
public void setNextHandler(AbstractHandler nextHandler){
this.nextHandler = nextHandler;
}
abstract void doFilter(HttpServletRequest request, HttpServletResponse response);
}
2、每個對象差異化處理
責任鏈上,每個對象的差異化處理,如本小節的業務場景,就有參數校驗對象、安全校驗對象、黑名單校驗對象、規則攔截對象。
/**
* 1、參數校驗對象
**/
@Component
@Order(1) //順序排第1,最先校驗
public class CheckParamFilterObject extends AbstractHandler {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response) {
System.out.println("1、非空參數檢查");
}
}
/**
* 2、安全校驗對象
*/
@Component
@Order(2) //校驗順序排第2
public class CheckSecurityFilterObject extends AbstractHandler {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response) {
//invoke Security check
System.out.println("2、安全調用校驗");
}
}
/**
* 3、黑名單校驗對象
*/
@Component
@Order(3) //校驗順序排第3
public class CheckBlackFilterObject extends AbstractHandler {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response) {
//invoke black list check
System.out.println("3、校驗黑名單");
}
}
/**
* 4、規則攔截對象
*/
@Component
@Order(4) //校驗順序排第4
public class CheckRuleFilterObject extends AbstractHandler {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response) {
//check rule
System.out.println("4、規則攔截對象");
}
}
3 對象鏈連起來(初始化)
/**
* @Description: 對象鏈連起來(初始化)對象
*/
@Component("ChainPatternDemo")
public class ChainPatternDemo {
//自動注入各個責任鏈的對象
@Autowired
private List<AbstractHandler> abstractHandleList;
private AbstractHandler abstractHandler;
//spring注入後自動執行,責任鏈的對象連接起來
@PostConstruct
public void initializeChainFilter(){
for(int i = 0;i<abstractHandleList.size();i++){
if(i == 0){
//因為上面@Order(1)拍過序 所以第一個就是 非空參數檢查
abstractHandler = abstractHandleList.get(0);
}else{
AbstractHandler currentHander = abstractHandleList.get(i - 1);
AbstractHandler nextHander = abstractHandleList.get(i);
currentHander.setNextHandler(nextHander);
}
}
}
//直接調用這個方法使用,返回最後處理好的response
public HttpServletResponse exec(HttpServletRequest request, HttpServletResponse response) {
//這裡 abstractHandler 就是第一個 接下來就會一個一個向下
abstractHandler.filter(request, response);
return response;
}
}
4、使用演示
@RestController
public class PayController {
@Autowired
private ChainPatternDemo chainPatternDemo;
@RequestMapping("/testHandler")
public void testHandler(HttpServletRequest req, HttpServletResponse resp){
//調用責任鏈
chainPatternDemo.exec(req,resp);
}
}
運行結果
1、非空參數檢查
2、安全調用校驗
3、校驗黑名單
4、規則攔截對象
完美!
總結
當我們在開發中有一個對象需要多次處理的時候,就可以考慮用責任鏈設計模式,上面的示例也完全可以用於實際開發中。
參考
1、實戰!工作中常用到哪些設計模式 非常感謝!