1. 程式人生 > 其它 >Java-責任鏈-設計模式(十六)

Java-責任鏈-設計模式(十六)

技術標籤:設計模式Java基礎設計模式java

說明

責任鏈模式(Chain of Responsibility)使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這個物件連城一條鏈,並沿著這條鏈傳遞請求,直到有一個物件處理它為止。

角色:
抽象處理者(Handler)角色:定義出一個處理請求的介面。如果需要,介面可以定義 出一個方法以設定和返回對下家的引用。這個角色通常由一個Java抽象類或者Java介面實現。Handler類的聚合關係給出了具體子類對下家的引用,抽象方法handleRequest()規範了子類處理請求的操作。
具體處理者(ConcreteHandler)角色

:具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。

程式碼

以張三發起一個請假或加薪的申請為例,審批人有主管,總監,總經理,各自許可權不同。
主管:只能處理兩天以內的請假請求,其餘的轉交給上級。
總監:許可一週以內的請假,其餘轉交給上級。
總經理:所有請假都批准;500以內加薪批准,超出500需要考慮。
此例參考《大話設計模式》,程式碼如下。

抽象處理者角色

/**
 * @author ctl
 * @date 2021/1/27
 * 管理者
 */
public abstract class Manager {

    protected
String name; // 上級 protected Manager superior; public Manager(String name) { this.name = name; } // 設定上級 public void setSuperior(Manager superior) { this.superior = superior; } // 申請 public abstract void request(Request request); }

具體處理者角色,主管

/**
 * @author ctl
 * @date 2021/1/27
 * 主管
 * 許可權:只能處理兩天以內的請假請求,其餘的轉交給上級
 */
public class CommonManager extends Manager { public CommonManager(String name) { super(name); } @Override public void request(Request request) { if ("請假".equals(request.getRequestType()) && request.getNum() <= 2) { System.out.println(name + ":" + request.getRequestContent() + " 數量" + request.getNum() + " 被批准"); } else { // 轉交上級 if (superior != null) { superior.request(request); } } } }

具體處理者角色,總監

/**
 * @author ctl
 * @date 2021/1/27
 * 總監
 * 許可權:許可一週以內的請假
 */
public class Majordomo extends Manager {
    public Majordomo(String name) {
        super(name);
    }

    @Override
    public void request(Request request) {
        if ("請假".equals(request.getRequestType()) && request.getNum() <= 5) {
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 數量" + request.getNum() + " 被批准");
        } else {
            // 轉交上級
            if (superior != null) {
                superior.request(request);
            }
        }
    }
}

具體處理者角色,總經理

/**
 * @author ctl
 * @date 2021/1/27
 * 總經理
 * 許可權:最高階,所有型別的請求都處理
 *      請假都批
 *      加薪500以下批,否則需要考慮
 */
public class GeneralManager extends Manager {

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

    @Override
    public void request(Request request) {
        // 請假 都批准
        if ("請假".equals(request.getRequestType())) {
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 數量" + request.getNum() + " 被批准");
        } else if ("加薪".equals(request.getRequestType()) && request.getNum() <= 500) {
            // 加薪 500以下批准 超過500 考慮考慮
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 數量" + request.getNum() + " 被批准");
        } else if ("加薪".equals(request.getRequestType()) && request.getNum() > 500) {
            System.out.println(name + ":" +
                    request.getRequestContent() +
                    " 數量" + request.getNum() + " 需要考慮考慮");
        }
    }
}

申請物件,封裝了申請內容

/**
 * @author ctl
 * @date 2021/1/27
 * 申請物件
 */
public class Request {

    // 申請型別
    private String requestType;

    // 申請內容
    private String requestContent;

    // 申請數量
    private int num;

    public String getRequestType() {
        return requestType;
    }

    public void setRequestType(String requestType) {
        this.requestType = requestType;
    }

    public String getRequestContent() {
        return requestContent;
    }

    public void setRequestContent(String requestContent) {
        this.requestContent = requestContent;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

測試類

/**
 * @author ctl
 * @date 2021/1/27
 */
public class ChainMain {

    public static void main(String[] args) {
        CommonManager commonManager = new CommonManager("主管");
        Majordomo majordomo = new Majordomo("總監");
        GeneralManager generalManager = new GeneralManager("總經理");
        // 設定上級,可以按需調整
        commonManager.setSuperior(majordomo);
        majordomo.setSuperior(generalManager);

        // 客戶端的每次申請都是由主管發出,內部具體的鏈路客戶端並不知曉
        Request request = new Request();
        request.setRequestType("請假");
        request.setRequestContent("張三請假");
        request.setNum(1);
        commonManager.request(request);

        Request request2 = new Request();
        request2.setRequestType("請假");
        request2.setRequestContent("張三請假");
        request2.setNum(4);
        commonManager.request(request2);

        Request request3 = new Request();
        request3.setRequestType("加薪");
        request3.setRequestContent("張三請求加薪");
        request3.setNum(500);
        commonManager.request(request3);

        Request request4 = new Request();
        request4.setRequestType("加薪");
        request4.setRequestContent("張三請求加薪");
        request4.setNum(1000);
        commonManager.request(request4);
    }
}

結果
結果
張三發起申請,只對接主管,最終根據設定的級別許可權,所有角色進行了對應的審批。

總結

責任鏈模式的好處就是接收者和傳送者彼此都不知道對方的角色,而且鏈中的物件自己也不知道鏈的結構。大大降低了耦合度。並且可以隨時按需修改處理一個請求的結構,增強了給物件指派指責的靈活性。