1. 程式人生 > 資訊 >富豪的太空競賽:馬斯克欲深空探索行業,貝索斯不甘出局

富豪的太空競賽:馬斯克欲深空探索行業,貝索斯不甘出局

職責鏈模式基本介紹

1)職責鏈模式( Chain oflResponsibility attern) ,又叫責任鏈模式,為請求建立了一個接收者物件的鏈(簡單示意圖)。這種模式對請求的傳送者和接收者進行解耦。
2)職責鏈模式通常每個接收者都包含對另一個接收者的引用。如果一個物件不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。

職責鏈模式原理類圖


對原理類圖的說明(職責鏈模式的角色及職責)
1.Handler:抽象的處理者,定義了一個處理請求的介面,同時含有另外的Hander
2.ConcreteHandlerA,B是具體的處理者,處理他自己負責的請求,可以訪問他的後繼者(下一個處理者),如果可以處理當前請求則自己處理,否則就將該請求交給後繼者去處理,從而形成職責鏈
3.Request:含有很多屬性,表示一個請求

職責鏈模式OA系統採購審批需求

學校OA系統的採購審批專案:需求是
1.採購員採購教學器材
2.如果金額 <= 5000,由教導主任審批
3.如果金額 <= 10000,由院長審批
4.如果金額 <= 30000,由副院長審批
5.如果金額 >= 10000,由校長審批
用程式完成此專案

程式碼實現

package com.cedric.responsibilitychain;

public abstract class Approver {

    Approver approver; // 下一個處理者
    String name;// 名字

    public Approver(String name){
        this.name = name;
    }

    // 下一個處理者
    public void setApprover(Approver approver){
        this.approver = approver;
    }

    // 處理審批請求的方法,得到一個請求,處理是子類完成,因此該方法做成抽象
    public abstract void processRequest(PurchaseRequest purchaseRequest);
}
package com.cedric.responsibilitychain;

public class DepartmentApprover extends Approver{

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

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice() <= 5000){
            System.out.println("請求編號" + purchaseRequest.getId() + "被" + this.name + "處理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }
}

package com.cedric.responsibilitychain;

public class CollegeApprover extends Approver{
    public CollegeApprover(String name){
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice() >= 5000 && purchaseRequest.getPrice() <= 10000){
            System.out.println("請求編號" + purchaseRequest.getId() + "被" + this.name + "處理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }
}

package com.cedric.responsibilitychain;

public class ViceSchoolMasterApprover extends Approver{
    public ViceSchoolMasterApprover(String name){
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice() >= 10000 && purchaseRequest.getPrice() <= 30000){
            System.out.println("請求編號" + purchaseRequest.getId() + "被" + this.name + "處理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }
}
package com.cedric.responsibilitychain;

public class SchoolMaster extends Approver{
    public SchoolMaster(String name){
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice() > 30000){
            System.out.println("請求編號" + purchaseRequest.getId() + " 被 " + this.name + " 處理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }
}
package com.cedric.responsibilitychain;

public class Client {
    public static void main(String[] args) {

        // 建立一個請求
        PurchaseRequest purchaseRequest  = new PurchaseRequest(1,1000,1);

        // 建立相關審批人
        DepartmentApprover departmentApprover = new DepartmentApprover("莫主任");
        CollegeApprover collegeApprover = new CollegeApprover("鍾院長");
        ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校長");
        SchoolMaster schoolMaster = new SchoolMaster("胡校長");

        // 需要將各個審批級別的下一個設定好(處理人構成環形)
        departmentApprover.setApprover(collegeApprover);
        collegeApprover.setApprover(viceSchoolMasterApprover);
        viceSchoolMasterApprover.setApprover(schoolMaster);
        schoolMaster.setApprover(departmentApprover);

        departmentApprover.processRequest(purchaseRequest);


    }
}

職責鏈模式的注意事項和細節

1.將請求和處理分開,實現解耦,提高系統的靈活性
2.簡化了物件,使物件不需要知道鏈的結構
3.效能會受到影響,特別是在鏈比較長的時候,因此需控制鏈中最大節點數量,一般通過在Handler中設定一個最大節點數量,
  在setNext()方法中判斷是否已經超過閾值,超過則不允許該表建立,避免出現超長鏈無意識的破壞系統性能
4.除錯不方便,採用了類似遞迴的方式,除錯時邏輯可能比較複雜
5.最佳應用場景:有多個物件可以處理同一個請求時,比如:多級請求、請假/加薪等審批流程、JavaWeb中的Tomacat
  對Encoding的處理、攔截器