目錄
- 1、使用demo演示責任鏈模式
- 2、傳統方案解決oa系統審批
- 3、傳統方案解決oa系統審批存在的問題
- 4、職責鏈模式基本介紹
- 5、職責鏈模式原理類圖
- 6、職責鏈模式解決oa系統采購審批
- 7、職責鏈模式的注意事項和細節
- 8、職責鏈模式的實際使用場景舉例
1、使用demo演示責任鏈模式
學校oa系統的采購審批項目:需求是
2、傳統方案解決oa系統審批
在一個類中對教學器材的價格進行判斷,然后根據判斷調用不同的審批者進行審批
3、傳統方案解決oa系統審批存在的問題
- 客戶端這里會使用分支判斷來對不用的采購請求進行處理,這樣就存在如下問題
- 如果各個級別的人員審批金額發生變化,客戶端也需要相應變化
- 客戶端必須明確知道有多少個審批級別
- 采購請求和審批人員之間存在強耦合關系,不利于代碼的擴展和維護
4、職責鏈模式基本介紹
職責鏈模式又稱為責任鏈模式:每個接收者都包含對另一個接收者的引用,如果一個對象不能處理該請求,那么它會把相同的請求傳給下一個接收者,依次類推
5、職責鏈模式原理類圖
對職責鏈模式的說明:
- Handler:抽象的處理者,定義了一個處理請求的方法,并且聚合了自身
- ConcreteHandlerA|B:是具體的處理者,處理它自己負責的請求,可以訪問它的后繼者,如果可以處理當前請求,則處理,否則將該請求交給下個后繼者去處理,從而形成一個職責鏈
6、職責鏈模式解決oa系統采購審批
1)類圖分析
2)代碼實現
// 購買請求
public class PurchaseRequest {//private int type;private float price;private int id;public PurchaseRequest(int type, float price, int id) {this.type = type;this.price = price;this.id = id;}public int getType() {return type;}public float getPrice() {return price;}public int getId() {return id;}
}// 審批者抽象類
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);
}/*** 部門主任*/
public class DepartmentApprover extends Approver {public DepartmentApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() <= 5000) {System.out.println("請求編號 id = " + purchaseRequest.getId() + "被" + this.name + "處理");} else {// 如果不能處理,則讓下一個處理者進行處理approver.processRequest(purchaseRequest);}}
}/*** 系主任*/
public class CollegeApprover extends Approver {public CollegeApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() > 5000 && purchaseRequest.getPrice() <= 10000) {System.out.println("請求編號 id = " + purchaseRequest.getId() + "被" + this.name + "處理");} else {// 如果不能處理,則讓下一個處理者進行處理approver.processRequest(purchaseRequest);}}
}/*** 副校長*/
public class ViceSchoolMasterApprover extends Approver {public ViceSchoolMasterApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() > 10000 && purchaseRequest.getPrice() <= 30000) {System.out.println("請求編號 id = " + purchaseRequest.getId() + "被" + this.name + "處理");} else {// 如果不能處理,則讓下一個處理者進行處理approver.processRequest(purchaseRequest);}}
}
/*** 校長*/
public class SchoolMasterApprover extends Approver {public SchoolMasterApprover(String name) {super(name);}@Overridepublic void processRequest(PurchaseRequest purchaseRequest) {if (purchaseRequest.getPrice() > 30000) {System.out.println("請求編號 id = " + purchaseRequest.getId() + "被" + this.name + "處理");} else {// 如果不能處理,則讓下一個處理者進行處理approver.processRequest(purchaseRequest);}}
}public class Client {public static void main(String[] args) {PurchaseRequest purchaseRequest = new PurchaseRequest(1, 31000, 1); DepartmentApprover departmentApprover = new DepartmentApprover("張主任");CollegeApprover collegeApprover = new CollegeApprover("李院長");ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("佟校長");//需要將各個審批級別的下一個設置好 (處理人構成環形: )departmentApprover.setApprover(collegeApprover);collegeApprover.setApprover(viceSchoolMasterApprover);viceSchoolMasterApprover.setApprover(schoolMasterApprover);schoolMasterApprover.setApprover(departmentApprover);departmentApprover.processRequest(purchaseRequest);}
}
7、職責鏈模式的注意事項和細節
- 將請求和處理分開,實現解耦,提高系統的靈活性
- 性能收到影響,特別是在鏈比較長的時候。因此需要控制鏈中最大節點數量,一般通過在Handler中設置一個
最大節點數量,在setNext方法中判斷是否已經超過閾值,超過則不允許建立改節點 - 由于采取了鏈的方式,所以調試邏輯比較復雜