已經把五個建立型設計模式和七個結構型設計模式介紹完了,從這篇開始要介紹行爲型設計模式了,第一個要介紹的行爲型設計模式就是責任鏈模式(又稱職責鏈模式)。html
責任鏈模式是爲了不請求的發送者和接收者之間的耦合關係,使多個接收對象都有機會處理請求。將這些對象練成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。固然責任鏈中也有可能沒有能夠處理該請求的對象,這種狀況是容許發生的。面試
仍是之前的規律,先舉出具體的代碼例子,而後再分析。拿前陣子在我老東家發生的一件事情來講,同事小王要結婚了,因此要請假回家籌備婚禮,可是公司有明確的規章制度,請假須要提早申請,而且每一級的領導可以審批的假期天數也不同,部門經理能夠審批1到2天的假期,技術總監可以審批3到5天的假期,大於5天的就要找CEO審批了,若是CEO審批經過了才能夠休息5天以上的假期,小王籌備婚禮和渡蜜月總共要請10個工做日的假期。設計模式
用代碼來實現這個過程就是下面👇這個樣子的。app
先建立請假條類ide
/** * 請假條 */ @Data @AllArgsConstructor public class Leave { /* 部門 */ private String department; /* 員工名稱 */ private String name; /* 請假天數 */ private double days; /* 請假事由 */ private String cause; }
而後建立審批人的抽象類post
/** * 審批人 */ public abstract class Approver { /* 審批人名稱 */ String name; /* 下一個審批人 */ Approver nextApprover; public Approver(String name){ this.name = name; } /** * 設置下一個審批人 * @param approver */ public void setNextApprover(Approver approver){ this.nextApprover = approver; } /** * 審批 * @param leave */ public abstract void approval(Leave leave); }
部門經理性能
/** * 部門經理 */ public class Manager extends Approver { /** * 設置名稱 * @param name 領導名稱 */ public Manager(String name) { super(name); } /** * 審批 * @param leave 請假條 */ @Override public void approval(Leave leave) { if(leave.getDays()<3){ System.out.println("請假小於3天,算臨時休息,批准了。"); System.out.println("部門經理審批經過---------審批流程over。"); }else{ if(Objects.nonNull(nextApprover)){ System.out.println("部門經理批准不了這麼多天的假期,須要上級審批。"); this.nextApprover.approval(leave); }else{ System.out.println(name+"的領導不在,等着吧。"); } } } }
技術總監學習
/** * 技術總監 */ public class TechnicalDirector extends Approver { /** * 設置名稱 * @param name 領導名稱 */ public TechnicalDirector(String name) { super(name); } /** * 審批 * @param leave 請假條 */ @Override public void approval(Leave leave) { if(leave.getDays()<5){ System.out.println("請假小於5天,算有事休息,批准了。"); System.out.println("技術總監審批經過---------審批流程over。"); }else{ if(Objects.nonNull(nextApprover)){ System.out.println("技術總監批准不了這麼多天的假期,須要上級審批。"); this.nextApprover.approval(leave); }else{ System.out.println(name+"的領導不在,等着吧。"); } } } }
CEO測試
/** * CEO */ public class CEO extends Approver { /** * 設置名稱 * @param name 領導名稱 */ public CEO(String name) { super(name); } /** * 審批 * @param leave 請假條 */ @Override public void approval(Leave leave) { if(leave.getDays()>5&&leave.getDays()<=10){ System.out.println("狀況特殊,批准了。"); System.out.println("CEO審批經過---------審批流程over。"); }else{ System.out.println(name+"說請假的時間太長了不批,最好別一次性請這麼久。"); } } }
測試類this
public class Client { public static void main(String[] args) { //寫請假條 Leave leave = new Leave("技術部","小王",6.0,"結婚"); //建立審批節點 Approver zhangge = new Manager("張哥"); Approver laozhao = new TechnicalDirector("老趙"); Approver lizong = new CEO("李總"); //將審批節點串起來 zhangge.setNextApprover(laozhao); laozhao.setNextApprover(lizong); //開始審批 zhangge.approval(leave); } }
運行結果
部門經理批准不了這麼多天的假期,須要上級審批。
技術總監批准不了這麼多天的假期,須要上級審批。
狀況特殊,批准了。
CEO審批經過---------審批流程over。
經過運行結果,咱們能夠看出來,當請假天數爲10天時,部門經理和技術總監都已經處理不了了,而後拋給了CEO,經過CEO特批小王的婚假請求才算了審批完成。這個例子就是用到了咱們今天說的責任鏈模式,下面繼續分析責任鏈模式。
抽象處理者(Handler)角色:抽象處理者用於定義出一個處理請求的接口,若是須要,接口能夠定義出一個方法,以返回對下一個處理對象的引用。上面例子中的Approver就是表明的這個角色。
具體處理者(ConcreteHandler)角色:處理接到的請求,能夠選擇將請求處理掉,或者將請求傳遞給下家。上面的例子中的Manager和TechnicalDirector以及CEO就是表明的這個角色。
一、請求不須要指出被哪一個對象處理了,這樣的效果是請求者和接收者之間的解耦,並且鏈中的對象也不須要清楚其餘鏈的結構,也下降了耦合。
二、請求處理對象僅須要維護一個指向其後繼者的的引用,而不須要維護全部的處理對象,簡化了對象之間的相互鏈接。
三、在給對象分派職責時,職責鏈能夠給咱們更多的靈活性,能夠經過在運行時對該鏈進行動態的增長或修改來增長或改變處理一個請求的職責。
四、新增一個請求處理對象,不須要改動現有代碼,只須要從新設置鏈接便可,符合「開閉原則」。
一、若是一個請求沒有明確的接收者,那麼就不能保證它必定會被處理,該請求可能一直到鏈的末端都得不處處理;一個請求也可能因職責鏈沒有被正確配置而得不處處理。
二、 對於比較長的職責鏈,請求的處理可能涉及到多個處理對象,不只增長了代碼的複雜性而且系統性能也將受到必定影響,並且在進行代碼調試時不太方便。
三、若建鏈不當,可能會形成循環調用,將致使系統陷入死循環。
一、有多個對象能夠處理同一個請求,具體哪一個對象處理該請求待運行時刻再肯定,客戶端只需將請求提交到鏈上,而無須關心請求的處理對象是誰以及它是如何處理的。
二、在不明確指定接收者的狀況下,向多個對象中的一個提交一個請求。
三、可動態指定一組對象處理請求,客戶端能夠動態建立職責鏈來處理請求,還能夠改變鏈中處理者之間的前後次序。
其實在咱們平常開發中也會有適用到責任鏈模式的場景,try/catch、servlet(各個servelt互相調用)、以及filter等
想了解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述。
如今是否是行業不景氣呢?怎麼最近連面試機會都少了?