《java設計模式》之責任鏈模式


在閻宏博士的《JAVA與模式》一書中開頭是這樣描述責任鏈(Chain of Responsibility)模式的:

  責任鏈模式是一種對象的行為模式。在責任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個對象最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。


在以下條件下可考慮使用Chain of Responsibility:
1 有多個的對象可以處理一個請求,哪個對象處理該請求運行時刻自動確定。
2 你想在不明確指定接受者的情況下,想過個對象中的一個提交一個請求。
3 可處理一個請求的對象集合應該被動態指定。

 


一個簡單的例子:

 1 abstract class Handler {
 2 
 3     private Handler nextHandler;
 4 
 5     public Handler getNextHandler() {
 6         return nextHandler;
 7     }
 8 
 9     public void setNextHandler(Handler nextHandler) {
10         this.nextHandler = nextHandler;
11     }
12 
13     public abstract void doHandler();
14 
15 }
16 
17 class ConcreteHandler extends Handler {
18 
19     @Override
20     public void doHandler() {
21 
22         if (getNextHandler() != null) {
23 
24             System.out.println("還有責任鏈");
25             getNextHandler().doHandler();
26         } else {
27 
28             System.out.println("我自己處理" + toString());
29         }
30 
31     }
32 }

 既然為設計模式,必然有其鮮明代碼的主體框架,我們來分析下

首先定義一個抽象的處理角色Handler ,其次是具體實現類ConcreteHandler ,在ConcreteHandler 我們通過getNextHandler()來判斷是否還有下一個責任鏈,如果有,則繼續

傳遞下去,調用getNextHandler().doHandler()來實現。

分析了簡單的責任鏈模式的代碼框架之后,我們接下來給代碼加點實際的功能,舉個很簡單的例子,就是報銷流程,項目經理<部門經理<總經理

其中項目經理報銷額度不能大於500,則部門經理的報銷額度是不大於1000,超過1000則需要總經理審核

 1 abstract class ConsumeHandler {
 2 
 3     private ConsumeHandler nextHandler;
 4 
 5     public ConsumeHandler getNextHandler() {
 6         return nextHandler;
 7     }
 8 
 9     public void setNextHandler(ConsumeHandler nextHandler) {
10         this.nextHandler = nextHandler;
11     }
12 
13     /** user申請人 free報銷費用 */
14     public abstract void doHandler(String user, double free);
15 
16 }
17 //項目經理
18 class ProjectHandler extends ConsumeHandler {
19 
20     @Override
21     public void doHandler(String user, double free) {
22         if (free < 500) {
23 
24             if (user.equals("lwx")) {
25                 System.out.println("給予報銷:" + free);
26             } else {
27                 System.out.println("報銷不通過");
28             }
29 
30         } else {
31             if (getNextHandler() != null) {
32 
33                 getNextHandler().doHandler(user, free);
34             }
35         }
36 
37     }
38 }
39 //部門經理
40 class DeptHandler extends ConsumeHandler {
41     
42     @Override
43     public void doHandler(String user, double free) {
44         if (free < 1000) {
45             
46             if (user.equals("zy")) {
47                 System.out.println("給予報銷:" + free);
48             } else {
49                 System.out.println("報銷不通過");
50             }
51             
52         } else {
53             if (getNextHandler() != null) {
54                 
55                 getNextHandler().doHandler(user, free);
56             }
57         }
58         
59     }
60 }
61 //總經理
62 class GeneralHandler extends ConsumeHandler {
63     
64     @Override
65     public void doHandler(String user, double free) {
66         if (free >=1000) {
67             
68             if (user.equals("lwxzy")) {
69                 System.out.println("給予報銷:" + free);
70             } else {
71                 System.out.println("報銷不通過");
72             }
73             
74         } else {
75             if (getNextHandler() != null) {
76                 
77                 getNextHandler().doHandler(user, free);
78             }
79         }
80         
81     }
82 }

測試下

 1 public static void main(String[] args) {
 2 
 3         /*ConcreteHandler handler1 = new ConcreteHandler();
 4         ConcreteHandler handler2 = new ConcreteHandler();
 5         handler1.setNextHandler(handler2);
 6         handler1.doHandler();*/
 7         
 8         ProjectHandler projectHandler =new ProjectHandler();
 9         DeptHandler deptHandler =new DeptHandler();
10         GeneralHandler generalHandler =new GeneralHandler();
11         projectHandler.setNextHandler(deptHandler);
12         deptHandler.setNextHandler(generalHandler);
13         projectHandler.doHandler("lwx", 450);
14         projectHandler.doHandler("lwx", 600);
15         projectHandler.doHandler("zy", 600);
16         projectHandler.doHandler("zy", 1500);
17         projectHandler.doHandler("lwxzy", 1500);
18     }

執行結果

給予報銷:450.0
報銷不通過
給予報銷:600.0
報銷不通過
給予報銷:1500.0

拓展聯想:模擬實現servlet過濾器中字符和登陸過濾器的實現

關於tomcat中責任鏈的使用:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html

 

 

 

 


免責聲明!

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



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