你們好,我是小趙,現任藏劍山莊高級鑄劍師,山莊的鑄劍師團隊一共有十多個組,我就是其中的小組長之一,我有七個手下。ide
今天,小明來找我請假,說他家裏出了點情況,須要請一個月的假,可我只是小組長,這麼長的假期我是沒權利作主的,我簽完字,就叫他去找部門經理,而後小明拿着請假條去找部門經理,部門經理簽字了,又讓小明去找總經理簽字,而後小明又拿着請假條去找總經理,最後總經理簽字,這個假纔算請完。性能
後來才知道,3天如下的假小組長簽字便可,3-7天的假須要小組長和部門經理簽字,7以上的假小組長和部門經理簽完字後還須要總經理簽字。優化
這個流程在各個企業裏面是很是常見的。this
我們就來研究一下這個請假的流程。spa
角色1:請假條,其實能夠理解成請假人,由於請假條上天然有請假人信息。設計
角色2:領導人,小組長、部門經理、總經理都是審批人。調試
動做:領導人審批請假條。code
那麼類圖也就能夠畫出來了:對象
如今咱們把程序寫出來,看看請假是怎麼請的:blog
請假條抽象:
public interface ILeave { String getName();//請假人姓名 int getNum();//請假天數 String getContent();//請假條內容 }
請假條:
public class Leave implements ILeave{ private String name;//姓名 private int num;//請假天數 private String content;//請假內容 public Leave(String name, int num, String content) { this.name = name; this.num = num; this.content = content; } public String getName() { return name; } public int getNum() { return num; } public String getContent() { return content; } }
處理者抽象:
public interface IHandler { void handleLeave(ILeave leave);//處理請假條 }
小組長:
public class GroupLeader implements IHandler { @Override public void handleLeave(ILeave leave) { System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。"); System.out.println("小組長審批:贊成。"); } }
部門經理:
public class Manager implements IHandler { @Override public void handleLeave(ILeave leave) { System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。"); System.out.println("部門經理審批:贊成。"); } }
總經理:
public class BigManager implements IHandler { @Override public void handleLeave(ILeave leave) { System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。"); System.out.println("總經理審批:贊成。"); } }
客戶端:
public static void main(String[] args) { //請假條來一張 ILeave leave = new Leave("小花",5,"身體不適"); //小組長第一個審批 IHandler groupLeader = new GroupLeader(); groupLeader.handleLeave(leave); if(leave.getNum() >= 3){ IHandler manager = new Manager(); manager.handleLeave(leave); } if(leave.getNum() >= 7){ IHandler bigManager = new BigManager(); bigManager.handleLeave(leave); } }
輸出:
小花請假5天,身體不適。
小組長審批:贊成。
小花請假5天,身體不適。
部門經理審批:贊成。
這個程序寫出來是有問題的。
若是老闆還要審批該怎麼辦?在外面繼續加個if判斷?一個優秀的程序應該具備高內聚低耦合的特性,這個程序審批規則寫在外面是不合理的。
正確的邏輯應該是什麼樣的呢? 應該是小花遞了請假條以後,就只須要等結果便可,而不是找了這個審批,回來後又跑去找那個審批。
對於請假制度的優化問題,我很是上心,若是我爲公司設計了健全的制度,說不定升職加薪就是分分鐘的事情。
主要要解決的問題就是職責隔離,小花是申請者,領導是審批者,至於審批規則應該是領導去把控,因此每一個領導須要知道本身的上級,也就是下一個審批人是誰。
因而可知,應該把interface改成abstract抽象類增長程序靈活度,使用模板方法模式將領導共同要遵照的規則收集到父類。
類圖畫出來也差很少,變化的只是處理者抽象:
請假條抽象:
public interface ILeave { String getName();//請假人姓名 int getNum();//請假天數 String getContent();//請假條內容 }
請假條:
public class Leave implements ILeave{ private String name;//姓名 private int num;//請假天數 private String content;//請假內容 public Leave(String name, int num, String content) { this.name = name; this.num = num; this.content = content; } public String getName() { return name; } public int getNum() { return num; } public String getContent() { return content; } }
處理者抽象:
public abstract class Handler { protected final static int NUM_ONE = 1; protected final static int NUM_THREE = 3; protected final static int NUM_SEVEN = 7; //該領導處理的請假天數區間 private int numStart = 0; private int numEnd = 0; //領導上面還有領導 private Handler nextHandler; //設置請假天數範圍 上不封頂 public Handler(int numStart) { this.numStart = numStart; } //設置請假天數範圍 public Handler(int numStart, int numEnd) { this.numStart = numStart; this.numEnd = numEnd; } //設置上級領導 public void setNextHandler(Handler nextHandler){ this.nextHandler = nextHandler; } //提交請假條 public final void submit(ILeave leave){ if(0 == this.numStart){ return; } //若是請假天數達到該領導者的處理要求 if(leave.getNum() >= this.numStart){ this.handleLeave(leave); //若是還有上級 而且請假天數超過了當前領導的處理範圍 if(null != this.nextHandler && leave.getNum() > numEnd){ this.nextHandler.submit(leave);//繼續提交 } } } //各級領導處理請假條方法 protected abstract void handleLeave(ILeave leave); }
小組長:
public class GroupLeader extends Handler { public GroupLeader() { //小組長處理1-3天的請假 super(Handler.NUM_ONE, Handler.NUM_THREE); } @Override protected void handleLeave(ILeave leave) { System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。"); System.out.println("小組長審批:贊成。"); } }
部門經理:
public class Manager extends Handler { public Manager() { //部門經理處理3-7天的請假 super(Handler.NUM_THREE, Handler.NUM_SEVEN); } @Override protected void handleLeave(ILeave leave) { System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。"); System.out.println("部門經理審批:贊成。"); } }
總經理:
public class BigManager extends Handler { public BigManager() { //部門經理處理7天以上的請假 super(Handler.NUM_SEVEN); } @Override protected void handleLeave(ILeave leave) { System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。"); System.out.println("總經理審批:贊成。"); } }
客戶端:
public static void main(String[] args) { //請假條來一張 ILeave leave = new Leave("小花",5,"身體不適"); //各位領導 Handler groupLeader = new GroupLeader(); Handler manager = new Manager(); Handler bigManager = new BigManager(); groupLeader.setNextHandler(manager);//小組長的領導是部門經理 manager.setNextHandler(bigManager);//部門經理的領導是總經理 //之因此在這裏設置上級領導,是由於能夠根據實際需求來更改設置,若是實戰中上級領導人都是固定的,則能夠移到領導實現類中。 //提交申請 groupLeader.submit(leave); }
輸出:
小花請假5天,身體不適。
小組長審批:贊成。
小花請假5天,身體不適。
部門經理審批:贊成。
責任鏈模式:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將整個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。
咱們能夠把各位領導想象成一條鏈,從鏈的開頭傳遞請求到盡頭,直到業務邏輯處理完成。
鏈上的每一個節點均可以設置本身處理的指標範圍,也能夠設置下一任處理者節點。
最顯著的好處就是請求者不用知道究竟是哪一個對象處理的,反正提交請求就對了。
同時鏈中的處理者並不知道整條鏈的結構,他們只須要保持一個指向下一任處理者對象的引用,這樣很是大的下降了耦合度。
責任鏈模式的缺點是性能問題,有可能一個請求是從整條鏈的頭部遍歷到鏈尾部,應該儘可能避免超長鏈,而且若是出現問題,調試很不方便。