一、概念
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、實戰!工作中常用到哪些設計模式 非常感謝!