文章出處

責任鏈模式,顧名思義,就是一條鏈。這個鏈到底是怎么運行的呢?它主要是將能夠處理同一類請求的對象連成一條鏈,所提交的請求沿著鏈傳遞,鏈上的對象逐個判斷是否有能力處理該請求,如果能則處理,如果不能則傳遞給鏈上的下一個對象進行處理,以此類推。 
  比如說公司請假需要審批,舉個不恰當的例子,如果請假小于3天,主管審批;3-10天的,經理審批;10-30天的,總經理審批;超過30天的,不批準等等。這就得一步步去判斷,如果撇開設計模式不看的話,那么我們可以使用if…else…把它解決了,但是問題可想而知,實際中的復雜程度時遠遠超過這個例子的。 
  下面使用責任鏈模式來實現一下這個場景,先來看一下它們之間的關系結構: 
這里寫圖片描述 
  Leader是個抽象類,里面有個方法是獲取下一個Leader,Director、Manager和GeneralManager分別繼承這個抽象類。LeaveRequest中封裝了請假的相關信息。下面來實現一下這個責任鏈模式。 
首先是封裝請假信息的類:

 

/**
 * @Description 封裝請假的基本信息
 * @author shanheyongmu
 *
 */
public class LeaveRequest {

    private String name;
    private int leaveDays;
    private String reason;

    public LeaveRequest(String name, int leaveDays, String reason) {
        super();
        this.name = name;
        this.leaveDays = leaveDays;
        this.reason = reason;
    }
    //省略get和set方法
}   

 

然后就是定義Leader這個抽象類了

/**
 * @Description 領導的抽象類
 * @author shanheyongmu
 *
 */
public abstract class Leader {

    protected String name;
    protected Leader nextLeader; //責任鏈上的后繼對象,即這個對象無法處理,就轉移給下一個Leader

    public Leader(String name) {
        super();
        this.name = name;
    }
    // 設定責任鏈上的后繼對象
    public void setNextLeader(Leader nextLeader) {
        this.nextLeader = nextLeader;
    }

    /**
     * 處理請求的核心的業務方法
     * 需要不同繼承該類的領導自己實現
     */
    public abstract void handleRequest(LeaveRequest request);

}

主管、經理和總經理都需要繼承該類,并實現處理請假的這個方法。

/**
 * @Description 主任
 * @author shanheyongmu
 *
 */
public class Director extends Leader {

    public Director(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {

        int days = request.getLeaveDays(); //獲取請假天數
        String name = request.getName(); //獲取請假人姓名
        String reason = request.getReason(); // 獲取請假理由

        if(days <= 3) { //如果滿足3天內的要求,主任直接審批
            System.out.println("員工" + name + "請假" + days + "天,理由:" + reason);
            System.out.println("主任" + this.name + "審批通過");
        } else {
            System.out.println("請假天數過多,主任" + this.name + "沒法處理");
            if(this.nextLeader != null) { //否則,如果鏈上存在下一個Leader,就讓他處理
                this.nextLeader.handleRequest(request);
            } 
        }
    }

}
/**
 * @Description 經理
 * @author shanheyongmu
 *
 */
public class Manager extends Leader {

    public Manager(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {

        int days = request.getLeaveDays(); //獲取請假天數
        String name = request.getName(); //獲取請假人姓名
        String reason = request.getReason(); // 獲取請假理由

        if(days <= 10) { //如果滿足10天內的要求,經理直接審批
            System.out.println("員工" + name + "請假" + days + "天,理由:" + reason);
            System.out.println("經理" + this.name + "審批通過");
        } else {
            System.out.println("請假天數過多,經理" + this.name + "沒法處理");
            if(this.nextLeader != null) { //否則,如果鏈上存在下一個Leader,就讓他處理
                this.nextLeader.handleRequest(request);
            } 
        }
    }

}
/**
 * @Description 總經理
 * @author shanheyongmu
 *
 */
public class GeneralManager extends Leader {

    public GeneralManager(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {

        int days = request.getLeaveDays(); //獲取請假天數
        String name = request.getName(); //獲取請假人姓名
        String reason = request.getReason(); // 獲取請假理由

        if(days <= 30) { //如果滿足30天內的要求,總經理直接審批
            System.out.println("員工" + name + "請假" + days + "天,理由:" + reason);
            System.out.println("總經理" + this.name + "審批通過");
        } else {
            System.out.println("請假天數過多,總經理" + this.name + "沒法處理");
            if(this.nextLeader != null) { //否則,如果鏈上存在下一個Leader,就讓他處理
                this.nextLeader.handleRequest(request);
            } else {
                System.out.println("請假不成功");
            }
        }
    }

}

由此可見,他們處理請求的條件是不同的,而且只要不是自己處理范圍之內的,就會將請求傳給鏈上的下一位來處理。接下來寫個客戶端模擬下:

 

public class Client {

    public static void main(String[] args) {

        Leader director = new Director("張三");
        Leader manager = new Manager("李四");
        Leader gManager = new GeneralManager("王五");

        // 組織好責任鏈對象的關系
        director.setNextLeader(manager);
        manager.setNextLeader(gManager);

        // 開始請假操作
        LeaveRequest request = new LeaveRequest("山河君", 15, "度假");
        director.handleRequest(request);
    }

}

 

運行結果:

請假天數過多 主任張三沒法處理
請假天數過多,經理李四沒法處理
員工山河君請假15天,理由: 度假
總經理王五審批通過

  在實際中,設置這個鏈可以放到配置文件中,可以直接修改配置文件即可,這個責任鏈模式擴展性也很好,比如現在有個副經理,專門處理10-20天的請假,那么我只要新添加一個副經理類即可,然后在責任鏈上配置一下就行了,對其他的類沒有影響。 
  責任鏈模式使用的地方很多,比如我們常見的try…catch…就是,可以有多個catch,一個個往下判斷;再比如servlet里面的過濾器,就是一個責任鏈;再比如struts2中的攔截器,也是使用的責任鏈模式。 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()