請求的鏈式處理——職責鏈模式(三)

來源:互聯網
上載者:User
16.3 完整解決方案

      為了讓採購單的審批次程序更加靈活,並實現採購單的鏈式傳遞和處理,Sunny公司開發人員使用職責鏈模式來實現採購單的分級審批,其基本結構16-3所示:

       在圖16-3中,抽象類別Approver充當抽象處理者(抽象傳遞者),Director、VicePresident、President和Congress充當具體處理者(具體傳遞者),PurchaseRequest充當請求類。完整代碼如下所示:
//採購單:請求類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

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.