設計模式-責任鏈模式


 

1 模式動機

為了降低系統的耦合度,將事件請求者和接收者解耦,我們可以使用命令模式來設計系統。通過增加不同的命令對象,不僅可以解耦,也可以有效解決發送和接收處理速度不一樣的問題。

 

2 模式定義

責任鏈模式(Chain of Responsibility Pattern):將多個對象連成一條鏈,沿着這條鏈傳遞請求,直到有一個對象處理它為止,使得多個對象都有機會處理該請求。

 

3 模式分析

Handler處理者接口:

    聲明處理請求的接口。

ConcreteHandler具體處理者類:

    實現處理請求的接口,指定下一處理者。

Client:

    調用客戶。

類圖如下所示:

 

4 實例演示

 1 package com.pattern.responsibility;
 2 
 3 public abstract class Handler {
 4     public Handler successor = null;
 5 
 6     public abstract boolean canHandle();
 7 
 8     public abstract void handle();
 9 
10     public void handleRequest() {
11         if(canHandle()) {
12             handle();
13         } else {
14             getSuccessor().handleRequest();
15         }
16     }
17 
18     public Handler getSuccessor() {
19         if(successor==null) {
20             successor = new EmptyHandler();
21         }
22         return successor;
23     }
24 
25     public void setSuccessor(Handler successor) {
26         this.successor = successor;
27     }
28 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class CommonHandler extends Handler {
 4     @Override
 5     public boolean canHandle() {
 6         // 是否可以處理請求
 7         System.out.println("Common not handle...");
 8         return false;
 9     }
10 
11     @Override
12     public void handle() {
13         System.out.println("Common handle...");
14     }
15 }

 

 1 package com.pattern.responsibility;
 2 public class SpecialHandler extends Handler {
 3     @Override
 4     public boolean canHandle() {
 5         // 具體handler實現
 6         System.out.println("Special not handle...");
 7         return false;
 8     }
 9 
10     @Override
11     public void handle() {
12         System.out.println("Special handle...");
13     }
14 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class ExtendHandler extends Handler {
 4     @Override
 5     public boolean canHandle() {
 6         // 是否可以處理請求
 7         return true;
 8     }
 9 
10     @Override
11     public void handle() {
12         System.out.println("Extend handle...");
13     }
14 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class EmptyHandler extends Handler {
 4     @Override
 5     public boolean canHandle() {
 6         // 是否可以處理請求
 7         return true;
 8     }
 9 
10     @Override
11     public void handle() {
12         // TODO Auto-generated method stub
13     }
14 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class Client {
 4     public static void main(String args[]) {
 5         CommonHandler commonHandler = new CommonHandler();
 6         SpecialHandler specialHandler = new SpecialHandler();
 7         ExtendHandler extendHandler = new ExtendHandler();
 8 
 9         commonHandler.setSuccessor(specialHandler);
10         specialHandler.setSuccessor(extendHandler);
11 
12         commonHandler.handleRequest();
13     }
14 }

 

5 純責任鏈與不純責任鏈

    純責任鏈:

1 handler能處理請求時,停止調用下一個handler。當handler不能處理請求時,繼續調用下一個handler。只能在兩個行為中選擇一個,一是承擔責任,二是把責任推給下家。

(好比男人要么做個有責任感的人,要么做個推卸責任的人)

2 一個請求必須被某一個處理者對象接收。

例如:工廠產品的質量檢查流水線,如果出現問題,就直接將產品拿出來。如果通過檢查,則傳遞給下一個檢查員。

不純責任鏈:

1 承擔一部分責任又把責任傳到下一個處理者(好比工廠的流水線,每處理完一道工序,交給下一個人處理)。

2 一個請求可以不被任何處理者接收。

例如:工廠產品的生產流水線,每個人都會處理一部分,然后交給下一個人。

 

6 優缺點

優點:

1 可以靈活方便的將處理者連接成一條鏈,滿足不同的需求。

2 將請求者與處理者解耦,提高靈活性。

 

缺點:

1 if...else...缺點一樣,在找到正確邏輯處理前,要遍歷每一個邏輯判斷,當責任鏈的對象過多時,會影響性能。

 

7 適用環境

1 有多個對象可以處理同一請求,處理請求的時機可以放在運行時確定。

 

8 總結

1 責任鏈模式最大的好處:可以根據需求組織對應的責任鏈處理請求,調用某個處理者即可,不用知道它內部的實現(它可以自己處理,也可以委托其它處理者處理)

 

9 問題

1 為什么不將處理器組成一個List,然后按順序處理請求?

  這樣請求可能被處理多次,在某些業務場景是不合適的(比如付款單發給多個付款者,則會發生多次付款)。這些場景處理者處理完畢后,不需要下一個處理者接着處理,這樣就不能用列表,而是通過責任鏈處理,當不需要往下傳遞時,馬上終止處理。

2 責任鏈模式最可能在什么場景下使用?

  當業務邏輯中包含多個ifelse分支,代碼看上去很糟糕時,可以考慮使用責任鏈模式將條件判斷邏輯分散到多個處理者對象中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM