Java设计模式之行为型:责任链模式
背景:
????????學校規定參加校招的同學必須要請假,且要有相關人員的簽字,三天以下需輔導員簽字、三到七天需要系主任簽字,一個星期以上需要院長簽字,更多的則需要校長簽字!
?????????上圖將學生、輔導員、系主任、院長、校長組成了一個簡單的鏈,在這個鏈上,學生是申請者,其余的都是請求處理者。對于這種將請求一級一級地往上傳遞直到請求被處理的設計模式就是職責鏈模式。
一、什么是責任鏈模式:
????????職責鏈可以將請求的處理者組織成一條鏈,并將請求沿著鏈傳遞,如果某個處理者能夠處理請求則處理,否則將該請求交由上級處理。客戶端只需將請求發送到職責鏈上,無須關注請求的處理細節,通過職責鏈將請求的發送者和處理者解耦了,這也是職責鏈的設計動機。????????
???????職責鏈模式可以簡化對象間的相互連接,因為客戶端和處理者都沒有對方明確的信息,同時處理者也不知道職責鏈中的結構,處理者只需保存一個指向后續者的引用,而不需要保存所有候選者的引用。
? ? ? ? 另外職責鏈模式增加了系統的靈活性,我們可以任意增加或更改處理者,甚至更改處理者的順序,不過有可能會導致一個請求無論如何也得不到處理,因為它可能被放置在鏈末端。
所以責任鏈模式有以下幾個優點:
- (1)降低耦合度,將請求的發送者和接收者解耦。反映在代碼上就是不需要在類中寫很多丑陋的 if….else 語句,如果用了職責鏈,相當于我們面對一個黑箱,只需將請求遞交給其中一個處理者,然后讓黑箱內部去負責傳遞就可以了。
- (2)簡化了對象,使得對象不需要鏈的結構。
- (3)增加系統的靈活性,通過改變鏈內的成員或者調動他們的次序,允許動態地新增或者刪除處理者
- (4)增加新的請求處理類很方便。
但是責任鏈模式也存在一些缺點:
- (1)不能保證請求一定被成功處理
- (2)系統性能將受到一定影響,并且可能會造成循環調用。
- (3)可能不容易觀察運行時的特征,而且在進行代碼調試時不太方便,有礙于除錯。
二、UML結構圖:
- ?(1)Handler:抽象處理者,定義了一個處理請求的方法。所有的處理者都必須實現該抽象類。?
- (2)ConcreteHandler:具體處理者,處理它所負責的請求,同時也可以訪問它的后繼者,如果它能夠處理該請求則處理,否則將請求傳遞到它的后繼者。
- (3)Client: 客戶類
下面是最典型的具體處理者類:
public class ConcreteHandler extends Handler {public void handleRequest(String request){if(請求request滿足條件){...... //處理請求;}else{this.successor.handleRequest(request); //轉發請求}} }三、代碼實現:
我們將使用開頭那個請假的實例。請假:3天以下輔導員簽字、3到5天系主任簽字、6到10天院長簽字、11-15天校長簽字、15天以上不允簽字。
首先是請假條:LeaveNode.java
public class LeaveNode {/** 請假天數 **/private int number;/** 請假人 **/private String person;public LeaveNode(String person,int number){this.person = person;this.number = number;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public String getPerson() {return person;}public void setPerson(String person) {this.person = person;} }抽象處理者:Leader.java
public abstract class Leader {/** 姓名 **/public String name;/** 后繼者 **/protected Leader successor;public Leader(String name){this.name = name;}public void setSuccessor(Leader successor) {this.successor = successor;}public abstract void handleRequest(LeaveNode LeaveNode); }四個具體處理者:輔導員:Instructor.java
public class Instructor extends Leader{public Instructor(String name){super(name);}public void handleRequest(LeaveNode LeaveNode) {if(LeaveNode.getNumber() <= 3){ //小于3天輔導員審批System.out.println("輔導員" + name + "審批" +LeaveNode.getPerson() + "同學的請假條,請假天數為" + LeaveNode.getNumber() + "天。");}else{ //否則傳遞給系主任if(this.successor != null){this.successor.handleRequest(LeaveNode);}}}}系主任: DepartmentHead.java
public class DepartmentHead extends Leader{public DepartmentHead(String name) {super(name);}public void handleRequest(LeaveNode LeaveNode) {if(LeaveNode.getNumber() <= 7){ //小于7天系主任審批System.out.println("系主任" + name + "審批" +LeaveNode.getPerson() + "同學的請假條,請假天數為" + LeaveNode.getNumber() + "天。");}else{ //否則傳遞給院長if(this.successor != null){this.successor.handleRequest(LeaveNode);}}} }?院長:Dean.java
public class Dean extends Leader{public Dean(String name) {super(name);}public void handleRequest(LeaveNode LeaveNode) {if(LeaveNode.getNumber() <= 10){ //小于10天院長審批System.out.println("院長" + name + "審批" +LeaveNode.getPerson() + "同學的請假條,請假天數為" + LeaveNode.getNumber() + "天。");}else{ //否則傳遞給校長if(this.successor != null){this.successor.handleRequest(LeaveNode);}}}}校長:President.java
public class President extends Leader{public President(String name) {super(name);}public void handleRequest(LeaveNode LeaveNode) {if(LeaveNode.getNumber() <= 15){ //小于15天校長長審批System.out.println("校長" + name + "審批" +LeaveNode.getPerson() + "同學的請假條,請假天數為" + LeaveNode.getNumber() + "天。");}else{ //否則不允批準System.out.println("請假天天超過15天,不批準...");}}}?客戶端:Client.java
public class Client {public static void main(String[] args) {Leader instructor = new Instructor("陳毅"); //輔導員Leader departmentHead = new DepartmentHead("王明"); //系主任Leader dean = new Dean("張強"); //院長Leader president = new President("王晗"); //校長instructor.setSuccessor(departmentHead); //輔導員的后續者是系主任departmentHead.setSuccessor(dean); //系主任的后續者是院長dean.setSuccessor(president); //院長的后續者是校長//請假3天的請假條LeaveNode leaveNode1 = new LeaveNode("張三", 3);instructor.handleRequest(leaveNode1); //請假9天的請假條LeaveNode leaveNode2 = new LeaveNode("李四", 9);instructor.handleRequest(leaveNode2);//請假15天的請假條LeaveNode leaveNode3 = new LeaveNode("王五", 15);instructor.handleRequest(leaveNode3);//請假20天的請假條LeaveNode leaveNode4 = new LeaveNode("趙六", 20);instructor.handleRequest(leaveNode4);} }運行結果:
四、純的與不純的責任鏈模式:
(1)純的責任鏈模式要求處理者對象只能在兩個行為中選擇一個:一是承擔責任,二是把責任推給下家,不允許出現某一個具體處理者對象在承擔了一部分責任后又把責任向下傳的情況。
(2)在純的責任鏈模式里面,請求必須被某一個處理者對象所接收;在不純的責任鏈模式里面,一個請求可以最終不被任何接收端對象所接收。
設計模式系列文章:
Java設計模式之創建型:工廠模式詳解(簡單工廠+工廠方法+抽象工廠)
Java設計模式之創建型:建造者模式
Java設計模式之創建型:單例模式
Java設計模式之創建型:原型模式
Java設計模式之結構型:適配器模式
Java設計模式之結構型:裝飾器模式
Java設計模式之結構型:代理模式
Java設計模式之結構型:橋接模式
Java設計模式之結構型:外觀模式
Java設計模式之結構型:組合模式
Java設計模式之結構型:享元模式
Java設計模式之行為型:策略模式
Java設計模式之行為型:模板方法模式
Java設計模式之行為型:責任鏈模式
Java設計模式之行為型:觀察者模式
Java設計模式之行為型:訪問者模式
Java設計模式之行為型:中介者模式
Java設計模式之行為型:命令模式
Java設計模式之行為型:狀態模式
Java設計模式之行為型:備忘錄模式
Java設計模式之行為型:迭代器模式
Java設計模式之行為型:解釋器模式
原博客鏈接:設計模式讀書筆記-----職責鏈模式_chenssy 的技術博客-CSDN博客
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Java设计模式之行为型:责任链模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java设计模式之行为型:迭代器模式
- 下一篇: Java设计模式之行为型:命令模式