請求的鏈式處理——職責鏈模式(三)
16.3 完整解決方案
為了讓採購單的審批流程更加靈活,並實現採購單的鏈式傳遞和處理,Sunny公司開發人員使用職責鏈模式來實現採購單的分級審批,其基本結構如圖16-3所示:
//採購單:請求類
class PurchaseRequest {
private double amount; //採購金額
private int number; //採購單編號
private String purpose; //採購目的
public PurchaseRequest(double amount, int number, String purpose) {
this.amount = amount;
this.number = number;
this.purpose = purpose;
}
public void setAmount(double amount) {
this.amount = amount;
}
public double getAmount() {
return this.amount;
}
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return this.number;
}
public void setPurpose(String purpose) {
this.purpose = purpose;
}
public String getPurpose() {
return this.purpose;
}
}
//審批者類:抽象處理者
abstract class Approver {
protected Approver successor; //定義後繼物件
protected String name; //審批者姓名
public Approver(String name) {
this.name = name;
}
//設定後繼者
public void setSuccessor(Approver successor) {
this.successor = successor;
}
//抽象請求處理方法
public abstract void processRequest(PurchaseRequest request);
}
//主任類:具體處理者
class Director extends Approver {
public Director(String name) {
super(name);
}
//具體請求處理方法
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 50000) {
System.out.println("主任" + this.name + "審批採購單:" + request.getNumber() + ",金額:" + request.getAmount() + "元,採購目的:" + request.getPurpose() + "。"); //處理請求
}
else {
this.successor.processRequest(request); //轉發請求
}
}
}
//副董事長類:具體處理者
class VicePresident extends Approver {
public VicePresident(String name) {
super(name);
}
//具體請求處理方法
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 100000) {
System.out.println("副董事長" + this.name + "審批採購單:" + request.getNumber() + ",金額:" + request.getAmount() + "元,採購目的:" + request.getPurpose() + "。"); //處理請求
}
else {
this.successor.processRequest(request); //轉發請求
}
}
}
//董事長類:具體處理者
class President extends Approver {
public President(String name) {
super(name);
}
//具體請求處理方法
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 500000) {
System.out.println("董事長" + this.name + "審批採購單:" + request.getNumber() + ",金額:" + request.getAmount() + "元,採購目的:" + request.getPurpose() + "。"); //處理請求
}
else {
this.successor.processRequest(request); //轉發請求
}
}
}
//董事會類:具體處理者
class Congress extends Approver {
public Congress(String name) {
super(name);
}
//具體請求處理方法
public void processRequest(PurchaseRequest request) {
System.out.println("召開董事會審批採購單:" + request.getNumber() + ",金額:" + request.getAmount() + "元,採購目的:" + request.getPurpose() + "。"); //處理請求
}
}
編寫如下客戶端測試程式碼: class Client {
public static void main(String[] args) {
Approver wjzhang,gyang,jguo,meeting;
wjzhang = new Director("張無忌");
gyang = new VicePresident("楊過");
jguo = new President("郭靖");
meeting = new Congress("董事會");
//建立職責鏈
wjzhang.setSuccessor(gyang);
gyang.setSuccessor(jguo);
jguo.setSuccessor(meeting);
//建立採購單
PurchaseRequest pr1 = new PurchaseRequest(45000,10001,"購買倚天劍");
wjzhang.processRequest(pr1);
PurchaseRequest pr2 = new PurchaseRequest(60000,10002,"購買《葵花寶典》");
wjzhang.processRequest(pr2);
PurchaseRequest pr3 = new PurchaseRequest(160000,10003,"購買《金剛經》");
wjzhang.processRequest(pr3);
PurchaseRequest pr4 = new PurchaseRequest(800000,10004,"購買桃花島");
wjzhang.processRequest(pr4);
}
}
主任張無忌審批採購單:10001,金額:45000.0元,採購目的:購買倚天劍。 副董事長楊過審批採購單:10002,金額:60000.0元,採購目的:購買《葵花寶典》。 董事長郭靖審批採購單:10003,金額:160000.0元,採購目的:購買《金剛經》。 召開董事會審批採購單:10004,金額:800000.0元,採購目的:購買桃花島。 |
如果需要在系統增加一個新的具體處理者,如增加一個經理(Manager)角色可以審批5萬元至8萬元(不包括8萬元)的採購單,需要編寫一個新的具體處理者類Manager,作為抽象處理者類Approver的子類,實現在Approver類中定義的抽象處理方法,如果採購金額大於等於8萬元,則將請求轉發給下家,程式碼如下所示:
//經理類:具體處理者
class Manager extends Approver {
public Manager(String name) {
super(name);
}
//具體請求處理方法
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 80000) {
System.out.println("經理" + this.name + "審批採購單:" + request.getNumber() + ",金額:" + request.getAmount() + "元,採購目的:" + request.getPurpose() + "。"); //處理請求
}
else {
this.successor.processRequest(request); //轉發請求
}
}
}
由於鏈的建立過程由客戶端負責,因此增加新的具體處理者類對原有類庫無任何影響,無須修改已有類的原始碼,符合“開閉原則”。
在客戶端程式碼中,如果要將新的具體請求處理者應用在系統中,需要建立新的具體處理者物件,然後將該物件加入職責鏈中。如在客戶端測試程式碼中增加如下程式碼:
Approver rhuang;
rhuang = new Manager("黃蓉");
將建鏈程式碼改為:
//建立職責鏈
wjzhang.setSuccessor(rhuang); //將“黃蓉”作為“張無忌”的下家
rhuang.setSuccessor(gyang); //將“楊過”作為“黃蓉”的下家
gyang.setSuccessor(jguo);
jguo.setSuccessor(meeting);
重新編譯並執行程式,輸出結果如下:
主任張無忌審批採購單:10001,金額:45000.0元,採購目的:購買倚天劍。 經理黃蓉審批採購單:10002,金額:60000.0元,採購目的:購買《葵花寶典》。 董事長郭靖審批採購單:10003,金額:160000.0元,採購目的:購買《金剛經》。 召開董事會審批採購單:10004,金額:800000.0元,採購目的:購買桃花島。 |
|
【作者:劉偉 http://blog.csdn.net/lovelion】
相關文章
- 請求的鏈式處理——職責鏈模式(四)模式
- 請求的鏈式處理——職責鏈模式(二)模式
- 請求的鏈式處理——職責鏈模式(一)模式
- 探索責任鏈模式:優雅處理複雜請求鏈模式
- 職責鏈模式模式
- 採購申請的處理流程 --- 責任鏈模式模式
- 設計模式-職責鏈模式設計模式
- 設計模式之-職責鏈模式設計模式
- 設計模式之【職責鏈模式】設計模式
- 職責鏈模式(chain of responsibility)模式AI
- 行為性職責鏈模式模式
- 設計模式系列 12– 職責鏈模式設計模式
- 簡說設計模式——職責鏈模式設計模式
- Javascript設計模式之職責鏈模式JavaScript設計模式
- JS設計模式五:職責鏈模式JS設計模式
- Python設計模式-職責鏈模式Python設計模式
- 【Zookeeper】原始碼分析之請求處理鏈(三)之SyncRequestProcessor原始碼
- javascript設計模式 之 10 職責鏈模式JavaScript設計模式
- C#設計模式之職責鏈模式C#設計模式
- 職責鏈模式的一篇文章模式
- PHP實現職責鏈設計模式PHP設計模式
- 實話設計模式之:職責鏈設計模式
- 設計模式(三) 責任鏈模式設計模式
- 設計模式(十六)職責鏈模式(Chain of Responsibility)設計模式AI
- 【Zookeeper】原始碼分析之請求處理鏈(一)原始碼
- (轉)職責鏈設計模式(Chain of Responsibility)設計模式AI
- 軟體設計模式學習(十七)職責鏈模式設計模式
- 使用職責鏈模式來重構你的程式碼模式
- 設計模式的征途—14.職責鏈(Chain of Responsibility)模式設計模式AI
- 責任鏈模式模式
- Activiti核心架構之職責鏈與命令模式架構模式
- C++設計模式——職責鏈模式( Chain of Responsibility Pattern)C++設計模式AI
- C#設計模式系列:職責鏈模式(Chain of Responsibility)C#設計模式AI
- JAVA設計模式之 職責鏈模式【Chain of Responsibility Pattern】Java設計模式AI
- 【Zookeeper】原始碼分析之請求處理鏈(二)之PrepRequestProcessor原始碼
- 責任鏈模式妙用模式
- 責任鏈模式探究模式
- 「責任鏈模式」栗子模式