请求的链式处理——职责链模式(三)

16.3 完整解决方案

      为了让采购单的审批流程更加灵活,并实现采购单的链式传递和处理,Sunny公司开发人员使用职责链模式来实现采购单的分级审批,其基本结构如图16-3所示:

        在图16-3中,抽象类Approver充当抽象处理者(抽象传递者),DirectorVicePresidentPresidentCongress充当具体处理者(具体传递者),PurchaseRequest充当请求类。完整代码如下所示:
[java]  view plain copy
  1. //采购单:请求类  
  2. class PurchaseRequest {  
  3.     private double amount;  //采购金额  
  4.     private int number;  //采购单编号  
  5.     private String purpose;  //采购目的  
  6.       
  7.     public PurchaseRequest(double amount, int number, String purpose) {  
  8.         this.amount = amount;  
  9.         this.number = number;  
  10.         this.purpose = purpose;  
  11.     }  
  12.       
  13.     public void setAmount(double amount) {  
  14.         this.amount = amount;  
  15.     }  
  16.       
  17.     public double getAmount() {  
  18.         return this.amount;  
  19.     }  
  20.       
  21.     public void setNumber(int number) {  
  22.         this.number = number;  
  23.     }  
  24.       
  25.     public int getNumber() {  
  26.         return this.number;  
  27.     }  
  28.       
  29.     public void setPurpose(String purpose) {  
  30.         this.purpose = purpose;  
  31.     }  
  32.       
  33.     public String getPurpose() {  
  34.         return this.purpose;  
  35.     }  
  36. }  
  37.   
  38. //审批者类:抽象处理者  
  39. abstract class Approver {  
  40.     protected Approver successor; //定义后继对象  
  41.     protected String name; //审批者姓名  
  42.       
  43.     public Approver(String name) {  
  44.         this.name = name;  
  45.     }  
  46.   
  47.     //设置后继者  
  48.     public void setSuccessor(Approver successor) {   
  49.         this.successor = successor;  
  50.     }  
  51.   
  52.     //抽象请求处理方法  
  53.     public abstract void processRequest(PurchaseRequest request);  
  54. }  
  55.   
  56. //主任类:具体处理者  
  57. class Director extends Approver {  
  58.     public Director(String name) {  
  59.         super(name);  
  60.     }  
  61.       
  62.     //具体请求处理方法  
  63.     public void processRequest(PurchaseRequest request) {  
  64.         if (request.getAmount() < 50000) {  
  65.             System.out.println("主任" + this.name + "审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getPurpose() + "。");  //处理请求  
  66.         }  
  67.         else {  
  68.             this.successor.processRequest(request);  //转发请求  
  69.         }     
  70.     }  
  71. }  
  72.   
  73. //副董事长类:具体处理者  
  74. class VicePresident extends Approver {  
  75.     public VicePresident(String name) {  
  76.         super(name);  
  77.     }  
  78.       
  79.     //具体请求处理方法  
  80.     public void processRequest(PurchaseRequest request) {  
  81.         if (request.getAmount() < 100000) {  
  82.             System.out.println("副董事长" + this.name + "审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getPurpose() + "。");  //处理请求  
  83.         }  
  84.         else {  
  85.             this.successor.processRequest(request);  //转发请求  
  86.         }     
  87.     }  
  88. }  
  89.   
  90. //董事长类:具体处理者  
  91. class President extends Approver {  
  92.     public President(String name) {  
  93.         super(name);  
  94.     }  
  95.       
  96.     //具体请求处理方法  
  97.     public void processRequest(PurchaseRequest request) {  
  98.         if (request.getAmount() < 500000) {  
  99.             System.out.println("董事长" + this.name + "审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getPurpose() + "。");  //处理请求  
  100.         }  
  101.         else {  
  102.             this.successor.processRequest(request);  //转发请求  
  103.         }  
  104.     }  
  105. }  
  106.   
  107. //董事会类:具体处理者  
  108. class Congress extends Approver {  
  109.     public Congress(String name) {  
  110.         super(name);  
  111.     }  
  112.       
  113.     //具体请求处理方法  
  114.     public void processRequest(PurchaseRequest request) {  
  115.         System.out.println("召开董事会审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getPurpose() + "。");        //处理请求  
  116.     }      
  117. }  
      编写如下客户端测试代码:  
[java]  view plain copy
  1. class Client {  
  2.     public static void main(String[] args) {  
  3.         Approver wjzhang,gyang,jguo,meeting;  
  4.         wjzhang = new Director("张无忌");  
  5.         gyang = new VicePresident("杨过");  
  6.         jguo = new President("郭靖");  
  7.         meeting = new Congress("董事会");  
  8.       
  9.         //创建职责链  
  10.         wjzhang.setSuccessor(gyang);  
  11.         gyang.setSuccessor(jguo);  
  12.         jguo.setSuccessor(meeting);  
  13.           
  14.         //创建采购单  
  15.         PurchaseRequest pr1 = new PurchaseRequest(45000,10001,"购买倚天剑");  
  16.         wjzhang.processRequest(pr1);  
  17.           
  18.         PurchaseRequest pr2 = new PurchaseRequest(60000,10002,"购买《葵花宝典》");  
  19.         wjzhang.processRequest(pr2);  
  20.       
  21.         PurchaseRequest pr3 = new PurchaseRequest(160000,10003,"购买《金刚经》");  
  22.         wjzhang.processRequest(pr3);  
  23.   
  24.         PurchaseRequest pr4 = new PurchaseRequest(800000,10004,"购买桃花岛");  
  25.         wjzhang.processRequest(pr4);  
  26.     }  
  27. }   
       编译并运行程序,输出结果如下:

主任张无忌审批采购单:10001,金额:45000.0元,采购目的:购买倚天剑。

副董事长杨过审批采购单:10002,金额:60000.0元,采购目的:购买《葵花宝典》。

董事长郭靖审批采购单:10003,金额:160000.0元,采购目的:购买《金刚经》。

召开董事会审批采购单:10004,金额:800000.0元,采购目的:购买桃花岛。

      如果需要在系统增加一个新的具体处理者,如增加一个经理(Manager)角色可以审批5万元至8万元(不包括8万元)的采购单,需要编写一个新的具体处理者类Manager,作为抽象处理者类Approver的子类,实现在Approver类中定义的抽象处理方法,如果采购金额大于等于8万元,则将请求转发给下家,代码如下所示:

[java]  view plain copy
  1. //经理类:具体处理者  
  2. class Manager extends Approver {  
  3.     public Manager(String name) {  
  4.         super(name);  
  5.     }  
  6.       
  7.     //具体请求处理方法  
  8.     public void processRequest(PurchaseRequest request) {  
  9.         if (request.getAmount() < 80000) {  
  10.             System.out.println("经理" + this.name + "审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getPurpose() + "。");  //处理请求  
  11.         }  
  12.         else {  
  13.             this.successor.processRequest(request);  //转发请求  
  14.         }     
  15.     }  
  16. }  

       由于链的创建过程由客户端负责,因此增加新的具体处理者类对原有类库无任何影响,无须修改已有类的源代码,符合“开闭原则”。

      在客户端代码中,如果要将新的具体请求处理者应用在系统中,需要创建新的具体处理者对象,然后将该对象加入职责链中。如在客户端测试代码中增加如下代码:

[java]  view plain copy
  1. Approver rhuang;  
  2. rhuang = new Manager("黄蓉");  

        将建链代码改为:

[java]  view plain copy
  1. //创建职责链  
  2. wjzhang.setSuccessor(rhuang); //将“黄蓉”作为“张无忌”的下家  
  3. rhuang.setSuccessor(gyang); //将“杨过”作为“黄蓉”的下家  
  4. gyang.setSuccessor(jguo);  
  5. jguo.setSuccessor(meeting);  

       重新编译并运行程序,输出结果如下:

主任张无忌审批采购单:10001,金额:45000.0元,采购目的:购买倚天剑。

经理黄蓉审批采购单:10002,金额:60000.0元,采购目的:购买《葵花宝典》。

董事长郭靖审批采购单:10003,金额:160000.0元,采购目的:购买《金刚经》。

召开董事会审批采购单:10004,金额:800000.0元,采购目的:购买桃花岛。

 

 

思考

       如果将审批流程由“主任-->副董事长-->董事长-->董事会”调整为“主任-->董事长-->董事会”,系统将做出哪些改动?预测修改之后客户端代码的输出结果。

 

【作者:刘伟 http://blog.csdn.net/lovelion

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值