責任鏈模式

請假有點麻煩

  你們好,我是小趙,現任藏劍山莊高級鑄劍師,山莊的鑄劍師團隊一共有十多個組,我就是其中的小組長之一,我有七個手下。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天,身體不適。
部門經理審批:贊成。

 

責任鏈模式

  責任鏈模式:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將整個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。

 

  咱們能夠把各位領導想象成一條鏈,從鏈的開頭傳遞請求到盡頭,直到業務邏輯處理完成。

  鏈上的每一個節點均可以設置本身處理的指標範圍,也能夠設置下一任處理者節點。

 

  最顯著的好處就是請求者不用知道究竟是哪一個對象處理的,反正提交請求就對了。

  同時鏈中的處理者並不知道整條鏈的結構,他們只須要保持一個指向下一任處理者對象的引用,這樣很是大的下降了耦合度。

 

  責任鏈模式的缺點是性能問題,有可能一個請求是從整條鏈的頭部遍歷到鏈尾部,應該儘可能避免超長鏈,而且若是出現問題,調試很不方便。

相關文章
相關標籤/搜索