java設計模式-職責鏈模式
模式導讀:
作為一名大學生,相信我們都有過請假的經歷,在我們請假是總會碰到這樣的場景,就是當請假的時間超過5天(包括5天),我們的請假條就不能由班主任進行審閱通過了,而是需要上交院系,由院領導進行審閱通過,當請假的時間超過一個月,就得由學校的教務處進行審閱通過。這便是在其位司其職,職責鏈模式也就相當於給了不同角色不同權限,權限低的不能去執行權限高的任務。
參考類圖:
責任鏈模式涉及到的角色如下所示:
● 抽象處理者(Handler)角色:定義出一個處理請求的接口。如果需要,接口可以定義 出一個方法以設定和返回對下家的引用。這個角色通常由一個Java抽象類或者Java接口實現。上圖中Handler類的聚合關系給出了具體子類對下家的引用,抽象方法handleRequest()規範了子類處理請求的操作。
● 具體處理者(ConcreteHandler)角色:具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。
代碼實現:
1.首先要有一個抽象的處理者類,在其中要包含對具體處理者角色的引用,同時定義一個處理請求的抽象方法
1 package com.etc; 2 //定義一個抽象的處理者類 3 public abstract class Handler { 4 public Handler sucesser; 5 6 //定義一個抽象的處理請求的方法 7public abstract String handlerRequest(String user,int days); 8 9 //獲取當前角色的下一個處理者角色 10 public Handler getNextHandler() { 11 return sucesser; 12 } 13 //設置當前角色的下一個處理者角色 14 public void setNextHandler(Handler sucesser) { 15 this.sucesser=sucesser; 16 }17 18 }
2.然後定義具體的處理者角色,根據不同情況加以判斷處理情況
(1)HeadTeacher.java
1 package com.etc; 2 //班主任處理請假請求 3 public class HeadTeacher extends Handler{ 4 @Override 5 public String handlerRequest(String user,int days) { 6 if(days<5) { 7 System.out.println("班主任同意"+user+"同學的請假請求"); 8 } 9 else { 10 System.out.println("班主任無法處理"+user+"同學的請假請求"); 11 } 12 if(getNextHandler()!=null) { 13 14 return getNextHandler().handlerRequest(user, days); 15 16 } 17 return null; 18 } 19 20 }
(2)Department.java
1 package com.etc; 2 //院系主任處理請假請求 3 public class Department extends Handler{ 4 5 @Override 6 public String handlerRequest(String user, int days) { 7 8 if(days<30 && days>=5) { 9 System.out.println("院系主任同意"+user+"同學的請假請求"); 10 } 11 else { 12 System.out.println("院系主任無法處理"+user+"同學的請假請求"); 13 } 14 if(getNextHandler()!=null) { 15 return getNextHandler().handlerRequest(user, days); 16 } 17 return null; 18 } 19 20 }
(3)Leader.java
1 package com.etc; 2 //校級主任處理請假請求 3 public class Leader extends Handler{ 4 5 @Override 6 public String handlerRequest(String user, int days) { 7 if(days>=30) { 8 System.out.println("校級主任同意"+user+"同學的請假請求"); 9 } 10 else if(getNextHandler()!=null) { 11 12 return getNextHandler().handlerRequest(user, days); 13 14 } 15 return null; 16 } 17 18 }
3.具體的客戶端類
1 package com.etc; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 //獲取三個不同的處理者對象 7 Handler h1=new HeadTeacher(); 8 Handler h2=new Department(); 9 Handler h3=new Leader(); 10 //設置角色的處理層次 11 h1.setNextHandler(h2); 12 h2.setNextHandler(h3); 13 14 h1.handlerRequest("張三", 3); 15 System.out.println("*************************"); 16 h1.handlerRequest("李四", 5); 17 System.out.println("*************************"); 18 h2.handlerRequest("王五", 15); 19 System.out.println("*************************"); 20 h2.handlerRequest("朱七", 30); 21 22 } 23 24 }
運行效果截圖:
職責鏈模式的優缺點:
優點:
(1) 職責鏈模式使得一個對象無須知道是其他哪一個對象處理其請求,對象僅需知道該請求會被處理即可,接收者和發送者都沒有對方的明確信息,且鏈中的對象不需要知道鏈的結構,由客戶端負責鏈的創建,降低了系統的耦合度。
(2) 請求處理對象僅需維持一個指向其後繼者的引用,而不需要維持它對所有的候選處理者的引用,可簡化對象的相互連接。
(3) 在給對象分派職責時,職責鏈可以給我們更多的靈活性,可以通過在運行時對該鏈進行動態的增加或修改來增加或改變處理一個請求的職責。
(4) 在系統中增加一個新的具體請求處理者時無須修改原有系統的代碼,只需要在客戶端重新建鏈即可,從這一點來看是符合“開閉原則”的。
缺點:
(1) 由於一個請求沒有明確的接收者,那麽就不能保證它一定會被處理,該請求可能一直到鏈的末端都得不到處理;一個請求也可能因職責鏈沒有被正確配置而得不到處理。
(2) 對於比較長的職責鏈,請求的處理可能涉及到多個處理對象,系統性能將受到一定影響,而且在進行代碼調試時不太方便。
(3) 如果建鏈不當,可能會造成循環調用,將導致系統陷入死循環。
適用場景:
(1) 有多個對象可以處理同一個請求,具體哪個對象處理該請求待運行時刻再確定,客戶端只需將請求提交到鏈上,而無須關心請求的處理對象是誰以及它是如何處理的。
(2) 在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
(3) 可動態指定一組對象處理請求,客戶端可以動態創建職責鏈來處理請求,還可以改變鏈中處理者之間的先後次序。
java設計模式-職責鏈模式