使用 Chrome Dev tools 分析應用的記憶體洩漏問題
阿新 • • 發佈:2021-10-02
職責鏈模式基本介紹
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的處理、攔截器