系統中若是存在多個對象能夠處理一個同一請求,能夠經過職責鏈模式將這些處理請求的對象連成一條鏈,讓請求沿着該鏈進行傳遞。若是鏈上的對象能夠處理該請求則進行處理,不然將請求轉發給下家處理html
不少狀況下,能夠處理某個請求的對象不止一個,如大學裏的獎學金審批,學生先向輔導員提交審批表,輔導員簽字審批後再交給系主任簽字審批,接着是院長審批,最後多是校長審批,在這個過程當中,獎學金申請表能夠看做一個請求對象,不一樣級別審批者均可以處理該請求,除了輔導員以外,學生不需一一和其餘審批者交互,只需等待結果便可。審批過程當中若是某一審批者認爲不符合條件,則請求停止,不然將請求傳遞給下一審批者,最後由校長拍板。java
在這個過程當中,輔導員、系主任、院長、校長構成一條鏈,申請表沿着這條鏈傳遞,就叫職責鏈。職責鏈能夠是一條直線、一個環或一個樹形結構,常見的職責鏈是直線型。請求沿着鏈傳遞,由鏈上的處理者對請求進行處理,客戶無須關心請求的處理和傳遞細節,實現請求發送者和請求處理者解耦。設計模式
避免請求者與接收者耦合在一塊兒,讓多個對象都有可能接受請求,將這些對象鏈接成一條鏈,而且沿着這條鏈傳遞請求,直到有對象處理爲止。職責鏈模式也叫責任鏈模式,它是一種對象行爲型模式。ide
Handler(抽象處理者)性能
定義了一個處理請求的接口,因爲不一樣的具體處理者處理請求方式不一樣,所以在其中定義抽象請求處理方法。在抽象處理者中定義一個自類型(抽象處理者類型)的對象,做爲對下家的引用。學習
ConcreteHandler(具體處理者)測試
具體處理者是抽象處理者子類,實現抽象請求處理方法,處理用戶請求。在處理請求以前要進行判斷,看是否具備相應處理權限,若是能夠處理就處理,不然將請求轉發給後繼者。this
Client(客戶類)設計
用於向鏈中對象提出最初的請求,客戶類只關心鏈的源頭,而無須關心請求的處理細節和傳遞過程。代理
某系統提供一個假條審批的模塊,若是員工請假天數小於 3 天,主任能夠審批該假條;若是員工請假天數大於等於 3 天,小於 10 天,經理能夠審批;若是員工請假天數大於等於 10 天,小於 30 天,總經理能夠審批;若是超過 30 天,總經理也不能審批,提示相應的拒絕信息。
請求類 LeaveRequest(請假條類)
// 封裝請求的相關信息,以便處理者對其進行處理 public class LeaveRequest { private String leaveName; private int leaveDays; public LeaveRequest(String leaveName, int leaveDays) { this.leaveName = leaveName; this.leaveDays = leaveDays; } public void setLeaveName(String leaveName) { this.leaveName = leaveName; } public void setLeaveDays(int leaveDays) { this.leaveDays = leaveDays; } public String getLeaveName() { return leaveName; } public int getLeaveDays() { return leaveDays; } }
抽象處理類 Leader(領導類)
public abstract class Leader { protected String name; protected Leader successor; // 做爲對下家的引用 public Leader(String name) { this.name = name; } public void setSuccessor(Leader successor) { this.successor = successor; } public abstract void handleRequest(LeaveRequest request); }
具體處理者 Director(主任類)
public class Director extends Leader { public Director(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if (request.getLeaveDays() < 3) { System.out.println("主任" + name + "審批員工" + request.getLeaveName() + "的請假條,請假天數爲" + request.getLeaveDays() + "天"); } else { if (this.successor != null) { this.successor.handleRequest(request); } } } }
具體處理者 Manager(經理類)
public class Manager extends Leader { public Manager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if (request.getLeaveDays() < 10) { System.out.println("經理" + name + "審批員工" + request.getLeaveName() + "的請假條,請假天數爲" + request.getLeaveDays() + "天"); } else { if (this.successor != null) { this.successor.handleRequest(request); } } } }
具體處理者 GeneralManager(總經理類)
public class GeneralManager extends Leader { public GeneralManager(String name) { super(name); } @Override public void handleRequest(LeaveRequest request) { if (request.getLeaveDays() < 30) { System.out.println("總經理" + name + "審批員工" + request.getLeaveName() + "的請假條,請假天數爲" + request.getLeaveDays() + "天"); } else { System.out.println("想請假" + request.getLeaveDays() + "天?你是不想幹了吧!"); } } }
客戶端測試類 Client
public class Client { public static void main(String[] args) { Leader director = new Director("王明"); Leader manager = new Manager("趙強"); Leader generalManager = new GeneralManager("陳勇"); director.setSuccessor(manager); manager.setSuccessor(generalManager); LeaveRequest lr1 = new LeaveRequest("張三", 2); director.handleRequest(lr1); LeaveRequest lr2 = new LeaveRequest("李四", 5); director.handleRequest(lr2); LeaveRequest lr3 = new LeaveRequest("王五", 15); director.handleRequest(lr3); LeaveRequest lr4 = new LeaveRequest("趙六", 45); director.handleRequest(lr4); } }
運行結果
職責鏈模式優勢以下:
職責鏈模式缺點以下:
如下狀況能夠考慮使用職責鏈模式:
一個純的職責鏈模式要求某一處理者對象要麼接收請求,承擔責任,要麼把責任推給下家。在一個不純的職責鏈模式裏面,一個請求能夠被由某一處理對象承擔一部分責任後,又將責任往下傳,或者最終不被任何接收端對象所接收。實際中咱們接觸到的大可能是不純的職責鏈模式。