責任鏈模式包含以下幾個角色:java
● Handler(抽象處理者):它定義了一個處理請求的接口,通常設計爲抽象類,因爲不一樣的具體處理者處理請求的方式不一樣,所以在其中定義了抽象請求處理方法。由於每個處理者的下家仍是一個處理者,所以在抽象處理者中定義了一個抽象處理者類型的對象(如結構圖中的successor),做爲其對下家的引用。經過該引用,處理者能夠連成一條鏈。 ● ConcreteHandler(具體處理者):它是抽象處理者的子類,能夠處理用戶請求,在具體處理者類中實現了抽象處理者中定義的抽象請求處理方法,在處理請求以前須要進行判斷,看是否有相應的處理權限,若是能夠處理請求就處理它,不然將請求轉發給後繼者;在具體處理者中能夠訪問鏈中下一個對象,以便請求的轉發。
一、主要優勢性能
(1) 責任鏈模式使得一個對象無須知道是其餘哪個對象處理其請求,對象僅需知道該請求會被處理便可,接收者和發送者都沒有對方的明確信息,且鏈中的對象不須要知道鏈的結構,由客戶端負責鏈的建立,下降了系統的耦合度。 (2) 請求處理對象僅需維持一個指向其後繼者的引用,而不須要維持它對全部的候選處理者的引用,可簡化對象的相互鏈接。 (3) 在給對象分派職責時,責任鏈能夠給咱們更多的靈活性,能夠經過在運行時對該鏈進行動態的增長或修改來增長或改變處理一個請求的職責。 (4) 在系統中增長一個新的具體請求處理者時無須修改原有系統的代碼,只須要在客戶端從新建鏈便可,從這一點來看是符合「開閉原則」的。
二、主要缺點測試
(1) 因爲一個請求沒有明確的接收者,那麼就不能保證它必定會被處理,該請求可能一直到鏈的末端都得不處處理;一個請求也可能因責任鏈沒有被正確配置而得不處處理。 (2) 對於比較長的責任鏈,請求的處理可能涉及到多個處理對象,系統性能將受到必定影響,並且在進行代碼調試時不太方便。 (3) 若是建鏈不當,可能會形成循環調用,將致使系統陷入死循環。
三、適用場景this
(1) 有多個對象能夠處理同一個請求,具體哪一個對象處理該請求待運行時刻再肯定,客戶端只需將請求提交到鏈上,而無須關心請求的處理對象是誰以及它是如何處理的。 (2) 在不明確指定接收者的狀況下,向多個對象中的一個提交一個請求。 (3) 可動態指定一組對象處理請求,客戶端能夠動態建立責任鏈來處理請求,還能夠改變鏈中處理者之間的前後次序
王者榮耀中的責任鏈模式(段位):設計
/** * 2018/12/6 * 抽象處理者 * * @author machuanpeng */ public abstract class Handler { //維持對下家的引用 protected Handler successor; public void setSuccessor(Handler successor) { this.successor=successor; } public abstract void handleRequest(int star); }
/** * 2018/12/6 * 青銅具體處理者 * * @author machuanpeng */ public class QingTongHandler extends Handler { public void handleRequest(int star) { if (star<10) { System.out.print("青銅段位"); } else { //轉發請求 this.successor.handleRequest(star); } } }
/** * 2018/12/6 * 白銀具體處理者 * * @author machuanpeng */ public class BaiYinHandler extends Handler { public void handleRequest(int star) { if (star<25) { System.out.print("白銀段位"); } else { //轉發請求 this.successor.handleRequest(star); } } }
/** * 2018/12/6 * 其餘具體處理者 * * @author machuanpeng */ public class QiTaHandler extends Handler { public void handleRequest(int star) { System.out.print("其餘段位"); } }
測試:調試
public class Client { public static void main(String args[]) { Handler qingTong = new QingTongHandler(); Handler baiYin = new BaiYinHandler(); Handler qiTa = new QiTaHandler(); qingTong.setSuccessor(baiYin); baiYin.setSuccessor(qiTa); qingTong.handleRequest(9); qingTong.handleRequest(20); qingTong.handleRequest(30); } }