職責鏈模式(Chain of Responsibility)的Java實現

職責鏈模式(Chain of Responsibility):使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。ide

適用場景:性能

一、有多個的對象能夠處理一個請求,哪一個對象處理該請求運行時刻自動肯定;測試

二、在不明確指定接收者的狀況下,向多個對象中的一個提交一個請求;this

三、處理一個請求的對象集合應被動態指定。spa

通用類圖:代理

在大學裏面當班幹部,時常要向上級申請各方面的東西。譬如申請全班外出秋遊,普通同窗將申請表交給班長,班長簽字以後交給輔導員,輔導員批准以後上交到主任辦公室…就是這樣,一個請求(這裏是一份申請表)有時候須要通過好幾個級別的處理者(這裏是輔導員、主任)的審查纔可以最終被肯定可行與否。對象

在這裏表現出來的是一個職責鏈,即不一樣的處理者對同一個請求可能擔負着不一樣的處理方式、權限,可是咱們但願這個請求必須到達最終拍板的處理者(不然秋遊就沒戲了)。這種關係就很適合使用職責鏈模式了。blog

類圖結構以下:遞歸

 代碼實現以下:接口

  
  
           
  
  
  1. // 全局變量,接口類型  
  2. /**  
  3.  * 使用Java中的interface定義全局變量,可根據具體須要在   
  4.  * 具體的包中使用靜態導入相關的全局變量,語法以下:   
  5.  *  import static package01.package02.*;  
  6.  */ 
  7. interface Levels {  
  8.     public static final int LEVEL_01 = 1;  
  9.     public static final int LEVEL_02 = 2;  
  10.     public static final int LEVEL_03 = 3;  

 

  
  
           
  
  
  1. // 抽象請求類  
  2. abstract class AbstractRequest {  
  3.     private String content = null;  
  4.  
  5.     public AbstractRequest(String content) {  
  6.         this.content = content;  
  7.     }  
  8.  
  9.     public String getContent() {  
  10.         return this.content;  
  11.     }  
  12.  
  13.     // 得到請求的級別  
  14.     public abstract int getRequestLevel();  

 

  
  
           
  
  
  1. // 具體請求類01  
  2. class Request01 extends AbstractRequest {  
  3.     public Request01(String content) {  
  4.         super(content);  
  5.     }  
  6.  
  7.     @Override 
  8.     public int getRequestLevel() {  
  9.         return Levels.LEVEL_01;  
  10.     }  
  11. }  
  12.  
  13. // 具體請求類02  
  14. class Request02 extends AbstractRequest {  
  15.     public Request02(String content) {  
  16.         super(content);  
  17.     }  
  18.  
  19.     @Override 
  20.     public int getRequestLevel() {  
  21.         return Levels.LEVEL_02;  
  22.     }  
  23. }  
  24.  
  25. // 具體請求類03  
  26. class Request03 extends AbstractRequest {  
  27.     public Request03(String content) {  
  28.         super(content);  
  29.     }  
  30.  
  31.     @Override 
  32.     public int getRequestLevel() {  
  33.         return Levels.LEVEL_03;  
  34.     }  

 

  
  
           
  
  
  1. // 抽象處理者類,  
  2. abstract class AbstractHandler {  
  3.     // 責任鏈的下一個節點,即處理者  
  4.     private AbstractHandler nextHandler = null;  
  5.  
  6.     // 捕獲具體請求並進行處理,或是將請求傳遞到責任鏈的下一級別  
  7.     public final void handleRequest(AbstractRequest request) {  
  8.  
  9.         // 若該請求與當前處理者的級別層次相對應,則由本身進行處理  
  10.         if (this.getHandlerLevel() == request.getRequestLevel()) {  
  11.             this.handle(request);  
  12.         } else {  
  13.             // 當前處理者不能勝任,則傳遞至職責鏈的下一節點  
  14.             if (this.nextHandler != null) {  
  15.                 System.out.println("當前 處理者-0" + this.getHandlerLevel()  
  16.                         + " 不足以處理 請求-0" + request.getRequestLevel());  
  17.                   
  18.                 // 這裏使用了遞歸調用  
  19.                 this.nextHandler.handleRequest(request);  
  20.             } else {  
  21.                 System.out.println("職責鏈上的全部處理者都不能勝任該請求...");  
  22.             }  
  23.         }  
  24.     }  
  25.  
  26.     // 設置責任鏈中的下一個處理者  
  27.     public void setNextHandler(AbstractHandler nextHandler) {  
  28.         this.nextHandler = nextHandler;  
  29.     }  
  30.  
  31.     // 獲取當前處理者的級別  
  32.     protected abstract int getHandlerLevel();  
  33.  
  34.     // 定義鏈中每一個處理者具體的處理方式  
  35.     protected abstract void handle(AbstractRequest request);  

 

  
  
           
  
  
  1. // 具體處理者-01  
  2. class Handler01 extends AbstractHandler {  
  3.     @Override 
  4.     protected int getHandlerLevel() {  
  5.         return Levels.LEVEL_01;  
  6.     }  
  7.  
  8.     @Override 
  9.     protected void handle(AbstractRequest request) {  
  10.         System.out.println("處理者-01 處理 " + request.getContent() + "\n");  
  11.     }  
  12. }  
  13.  
  14. // 具體處理者-02  
  15. class Handler02 extends AbstractHandler {  
  16.     @Override 
  17.     protected int getHandlerLevel() {  
  18.         return Levels.LEVEL_02;  
  19.     }  
  20.  
  21.     @Override 
  22.     protected void handle(AbstractRequest request) {  
  23.         System.out.println("處理者-02 處理 " + request.getContent()+ "\n");  
  24.     }  
  25. }  
  26.  
  27. // 具體處理者-03  
  28. class Handler03 extends AbstractHandler {  
  29.     @Override 
  30.     protected int getHandlerLevel() {  
  31.         return Levels.LEVEL_03;  
  32.     }  
  33.  
  34.     @Override 
  35.     protected void handle(AbstractRequest request) {  
  36.         System.out.println("處理者-03 處理 " + request.getContent()+ "\n");  
  37.     }  

 

  
  
           
  
  
  1. // 測試類  
  2. public class Client {  
  3.     public static void main(String[] args) {  
  4.         // 建立指責鏈的全部節點  
  5.         AbstractHandler handler01 = new Handler01();  
  6.         AbstractHandler handler02 = new Handler02();  
  7.         AbstractHandler handler03 = new Handler03();  
  8.  
  9.         // 進行鏈的組裝,即頭尾相連,一層套一層  
  10.         handler01.setNextHandler(handler02);  
  11.         handler02.setNextHandler(handler03);  
  12.  
  13.         // 建立請求並提交到指責鏈中進行處理  
  14.         AbstractRequest request01 = new Request01("請求-01");  
  15.         AbstractRequest request02 = new Request02("請求-02");  
  16.         AbstractRequest request03 = new Request03("請求-03");  
  17.           
  18.         // 每次提交都是從鏈頭開始遍歷  
  19.         handler01.handleRequest(request01);  
  20.         handler01.handleRequest(request02);  
  21.         handler01.handleRequest(request03);  
  22.     }  

測試結果:

  
  
           
  
  
  1. 處理者-01 處理 請求-01 
  2.  
  3. 當前 處理者-01 不足以處理 請求-02 
  4. 處理者-02 處理 請求-02 
  5.  
  6. 當前 處理者-01 不足以處理 請求-03 
  7. 當前 處理者-02 不足以處理 請求-03 
  8. 處理者-03 處理 請求-03 
在上面抽象處理者 AbstractHandler 類的 handleRequest() 方法中,被 protected 修飾,而且該方法中調用了兩個必須被子類覆蓋實現的抽象方法,這裏是使用了模板方法模式(Template Mehtod)。其實在這裏,抽象父類的 handleRequest() 具有了請求傳遞的功能,即對某些請求不能處理時,立刻提交到下一結點(處理者)中,而每一個具體的處理者僅僅完成了具體的處理邏輯,其餘的都不用理。
 
記得第一次看到職責鏈模式的時候,我很驚訝於它可以把咱們平時在代碼中的 if..else.. 的語句塊變成這樣靈活、適應變化。例如:若是如今輔導員請長假了,但咱們的秋遊仍是要爭取申請成功呀,那麼咱們在 Client 類中能夠不要建立 handler02,即不要將該處理者組裝到職責鏈中。這樣子處理比 if..else..好多了。或者說,忽然來了個愛管閒事的領導,那麼我照樣能夠將其組裝到職責鏈中。
 
關於上面使用場景中提到的3個點:
一、處理者在運行時動態肯定實際上是咱們在 Client 中組裝的鏈所引發的,由於具體的職責邏輯就在鏈中一一對應起來;
二、由於不肯定請求的具體處理者是誰,因此咱們把全部可能的處理者組裝成一條鏈,在遍歷的過程當中就至關於向每一個處理者都提交了這個請求,等待其審查。而且在審查過程當中,即便不是最終處理者,也能夠進行一些請求的「包裝」操做(這種功能相似於裝飾者模式),例如上面例子中的簽名批准;
三、處理者集合的動態指定跟上面的第一、2點相似,即在 Client 類中建立了全部可能的處理者。
 
不足之處:

一、對於每個請求都須要遍歷職責鏈,性能是個問題;

二、抽象處理者 AbstractHandler 類中的 handleRequest() 方法中使用了遞歸,棧空間的大小也是個問題。

 我的見解:

職責鏈模式對於請求的處理是不知道最終處理者是誰,因此是運行動態尋找並指定;而命令模式中對於命令的處理時在建立命令是已經顯式或隱式綁定了接收者。

相關文章:

命令模式(Command)的兩種不一樣實現(http://haolloyin.blog.51cto.com/1177454/339076

(Template Method)模板方法模式的Java實現(http://haolloyin.blog.51cto.com/1177454/333063

裝飾模式(Decorator)與動態代理的強強聯合(http://haolloyin.blog.51cto.com/1177454/338671

相關文章
相關標籤/搜索