Java资源网

| JAVA基础 | 环境配置 | JDBC | 线程技术 | Socket编程 | JavaMail | JAVA与XML | 设计模式 | 技术新闻 | Java认证 | 程序人生 软件下载
| JSP&Servlet | Spring | Struts | Hibernate | JBuilder | Eclipse | WebService | EJB技术 | J2ME开发 | 应用服务器 | JXTA | Ajax
Articles search文章搜索
   关键字:
   类 别:
       
New download 最新下载
· [组件]HTML Parser 1.5
· [教程]WebSphere Studio应用教程
· [组件]JDom 1.0
· [工具]Junit3.8.1
· [教程]EJB编程及J2EE系统架构和设计
· [教程]EJB教程
· [教程]J2EE Tutorial中文版
· [教程]Java编程思想2(英文)
· [教程]java编程思想(完整版)
· [教程]Java网络编程
New articles 最新文章
· 设计移动 Web 服务
· 解析XML的时候完全忽略DTD
· 理解XML Schema XML Schema 初步
· 标签库的深入研究
· 提升JSP应用程序的七大绝招
· 如何使用JDOM对XML文件进行操作
· 处理XML字符串中特殊字符
· 利用Digester把XML转换成为Java对象
· 使用WebService 和RMI远程协作
· 使用Axis开发Web Service程序
Articles top 热门文章
· Eclipse基础--plugin插件安装(6644)
· eclipse+tomcat+lomboz的安装配置说明(4774)
· Java程序员就业前景(4584)
· Windows下JAVA环境变量的设置祥解(3788)
· Tomcat下JSP、Servlet和JavaBean环境的配置(3716)
· 使用links方式安装Eclipse插件(3698)
· 一个老程序员的心理话(3533)
· linux下jdk的安装与配置(3459)
· 初学者入门:Structs中基本配置入门(3334)
· Eclipse 运行命令行参数大全(3084)
您的位置:首页>>设计模式>>责任链模式(Chainnbsp;ofnbsp;Responsibility)
责任链模式(Chainnbsp;ofnbsp;Responsibility)
2007-04-13   来源:www.javaresearch.org  作者:未知

第21章 责任链模式(Chain of Responsibility)

描述:


    责任链模式(CoR)建议发出请求的对象与可能处理这个请求的对象集合之间是低耦合的(set of potential request handler objects)。
    在有不止一个对象可以处理或实现(fulfill)客户请求的时候,责任链模式(CoR)认为顺序地给每一个对象一次处理请求的机会。在这种情况下应用责任链模式(CoR),把每一个可能处理请求的对象以链表的形式组织起来,在链表中,每一个对象有一个指向下一个对象的指针(Pointer)。在链表中的第一个对象接受请求并且决定是否处理它,或者把它传递
给下一个对象。请求一个接一个地遍历(flow through)链表中的所有对象,直到请求被其中的一个对象处理或者因到达链表尾而没有被处理。
    例如:如果A?〉B?〉C都可以处理请求,按照这个顺序,A处理请求或者在不知B是否可以处理这个请求的情况下递给B。接受到请求的B可以处理这个请求或者传递给C。
当C收到请求时,这个请求可以被C处理或者没有经过任何处理而结束。换句话说,提交的处理链表中的请求在到达链表尾前,可以不被任何处理。
    下面是责任链模式(CoR)一些重要的特征:
(1)    可能处理请求的对象集合(set of potential request handler objects)以及它们在链表中的顺序是由客户端根据现应用的状态在运行时动态决定的。
(2)    客户端根据现在的状态,对于不同的请求类型,可以拥有不同的可能处理请求的对象集合(set of potential request handler objects)。一个处理请求的对象也可以根据客户应用的状态和请求类型,把请求传递给不同的处理对象。为了使这些交互简单,所有的可能处理请求的对象应提供一致的接口。在JAVA中,不同处理对象可以实现一个共同的接口或者继承同一个抽象的父类来实现。
(3)    客户对象初始化请求,或者在不知道这些对象是否能处理这个请求的情况下初始化任何可能处理请求的对象。也就是说,客户对象和在处理链表中的处理对象都不需要知道到底哪个对象去处理这个请求。
(4)    请求不能保证被处理。也就是,在没有处理的情况下,请求已经到达了处理链表尾。下面的这个情景展示了一个购买请求传递到处理链表中,但是在到达链表尾时,并没有被接受。

例子


    让我们模拟一个在特定组织里的购买请求(PR)授权过程的应用。通常,在确立订单并发到卖方前,一个购买请求是需要不同的管理代表授权的。我们假定一个组织中在购买请求金额限制上分为四个授权管理层次,如下面的列表:






Table 21.1: Levels of PR Authorization 
Management Level     Authorization Limit 
Branch Manager    $25,000
Regional Director    $100,000
Vice President    $200,000
President and COO    $400,000

我们可以定义不同的类,来对应上面列表中的不同管理层次。
Listing 21.1: Classes Representing Different Management Levels 
  1. class BranchManager { 
  2.   static double LIMIT = 25000; 
  3.           … 
  4.           … 
  5. }//End of class 
  6. class RegionalDirector { 
  7.   static double LIMIT = 100000; 
  8.           … 
  9.           … 
  10. }//End of class 
  11. class VicePresident { 
  12.   static double LIMIT = 200000; 
  13.           … 
  14.           … 
  15. }//End of class 
  16. class PresidentCOO { 
  17.   static double LIMIT = 400000; 
  18.           … 
  19.           … 
  20. }//End of class 

   让我们定义一个PurchaseRequest类,它代表购买请求。


PurchaseRequest 
ID:int 
description:String 
amount:double 
getAmount():double 

Figure 21.1: PurchaseRequest Class Representation
Listing 21.2: PurchaseRequest Class 
  1. class PurchaseRequest { 
  2.   private int ID; 
  3.   private String description; 
  4.   private double amount; 
  5.   public PurchaseRequest(int id, String desc, double amt) { 
  6.     ID = id; 
  7.     description = desc; 
  8.     amount = amt; 
  9.   } 
  10.   public double getAmount() { 
  11.     return amount; 
  12.   } 
  13.   public String toString() { 
  14.     return ID + ":" + description; 
  15.   } 

    一个给定的购买请求(PR)被上面的管理代表所授权或处理。换句话说,代表不同管理层次的四个类都是处理给定购买请求的可能处理者(授权者)。因此,不建议PurchaseRequest实例榜定到任何的一个授权者。通过使用责任链模式(CoR),实现了PurchaseRequest对象和可能授权请求的对象集合之间关联的低耦合。
    利用责任链模式(CoR),让我们定义一个抽象类PRHandler,它定义这些可能授权购买请求对象的统一接口。
Listing 21.3: Abstract PRHandler Class 
  1. public abstract class PRHandler { 
  2.   private PRHandler nextHandler; 
  3.   private String handlerName; 
  4.   public PRHandler(String name) { 
  5.     handlerName = name; 
  6.   } 
  7.   public String getName() { 
  8.     return handlerName; 
  9.   } 
  10.   public abstract boolean authorize(PurchaseRequest request); 
  11.   public PRHandler getNextHandler() { 
  12.     return nextHandler; 
  13.   } 
  14.   public void setNextHandler(PRHandler handler) { 
  15.     nextHandler = handler; 
  16.   }; 
 


Figure 21.2: Purchase Request Approver Hierarchy 
现在,每一个授权者被重新定义为抽象类PRHandler的子类。每一个授权对象把购买请求的金额和它所在的管理层次所授权的金额进行比较,如果请求的金额小于授权的金额,它就可以授权购买,如果大于,它传递购买请求到链表中的下一个授权者。
Listing 21.4: PRHandler Concrete Subclasses 
  1. class BranchManager extends PRHandler { 
  2.   static double LIMIT = 25000; 
  3.   public BranchManager(String name) { 
  4.     super(name); 
  5.   } 
  6.   public boolean authorize(PurchaseRequest request) { 
  7.     double amount = request.getAmount(); 
  8.     if (amount <= LIMIT) { 
  9.       System.out.println(" Branch Manager " + getName() + 
  10.                          " has authorized the PR − " + request); 
  11.       return true
  12.     } else { 
  13.       //forward the request to the next handler 
  14.       return getNextHandler().authorize(request); 
  15.     } 
  16.   } 
  17. }//End of class 
  18. class RegionalDirector extends PRHandler { 
  19.   static double LIMIT = 100000; 
  20.   public RegionalDirector(String name) { 
  21.     super(name); 
  22.   } 
  23.   public boolean authorize(PurchaseRequest request) { 
  24.     double amount = request.getAmount(); 
  25.     if (amount <= LIMIT) { 
  26.       System.out.println(" Regional Director " + getName() + 
  27.                          " has authorized the PR − " + 
  28.                          request); 
  29.       return true
  30.     } else { 
  31.       //forward the request to the next handler 
  32.       return getNextHandler().authorize(request); 
  33.     } 
  34.   } 
  35. }//End of class 
  36. class VicePresident extends PRHandler { 
  37.   static double LIMIT = 200000; 
  38.   public VicePresident(String name) { 
  39.     super(name); 
  40.   } 
  41. public boolean authorize(PurchaseRequest request) { 
  42.   double amount = request.getAmount(); 
  43.   if (amount <= LIMIT) { 
  44.     System.out.println(" V.P. " + getName() + 
  45.                        " has authorized the PR − " + request); 
  46.     return true
  47.   } else { 
  48.     //forward the request to the next handler 
  49.     return getNextHandler().authorize(request); 
  50.   } 
  51. }//End of class 
  52. class PresidentCOO extends PRHandler { 
  53.   static double LIMIT = 400000; 
  54.   public PresidentCOO(String name) { 
  55.     super(name); 
  56.   } 
  57.   public boolean authorize(PurchaseRequest request) { 
  58.     double amount = request.getAmount(); 
  59.     if (amount <= LIMIT) { 
  60.       System.out.println(" President & COO " + getName() + 
  61.                          " has authorized the PR − " + request); 
  62.       return true
  63.     } else { 
  64.       System.out.println("PR − " + request + 
  65.                          " couldn't be authorized.\n " + 
  66.                          "Executive Board needs to be " + 
  67.                          "consulted for approval \n" + 
  68.                          "reason: Amount too large"); 
  69.       return false
  70.     } 
  71.   } 
  72. }//End of class 

  为了授权购买请求,客户端需要:
(1)    创建一个可能接受购买请求的授权对象集合,把他们按照授权金额升序进行排列,使用setNextHandler(PRHandler)方法,连接每一个授权者。下面是可能的授权购买请求的授权链表:
 
Figure 21.3: Chain of PR Authorization Request Handlers
(2)    发送一个购买请求到链表中的第一个PRHander对象,把购买请求对象作为参数传递给authorize方法,并调用这个方法。从不同的PRHander子类的实现可以看到,如果购买请求(PR)数额小于特定授权的数额,购买请求(PR)就被授权。否则,购买请求(PR)传递到链表中的下一个授权对象。如果购买请求(PR)就被一个处理者授权,它就不继续传递。在这个例子中购买请求是不能保证都被处理的,如果请求到达了链表尾而且请求数额大于最后一个处理者的授权数额,则显示一个合适的消息,购买请求仍然没有授权。
Listing 21.5: Client PRManager Class 
  1. public class PRManager { 
  2.   private BranchManager branchManager; 
  3.   private RegionalDirector regionalDirector; 
  4.   private VicePresident vicePresident; 
  5.   private PresidentCOO coo; 
  6.   public static void main(String[] args) { 
  7.     PRManager manager = new PRManager(); 
  8.     manager.createAuthorizationFlow(); 
  9.     PurchaseRequest request = 
  10.       new PurchaseRequest(1, "Office Supplies”,10000); 
  11.     manager.branchManager.authorize(request); 
  12.     request = new PurchaseRequest(2, "HardWare Procurement”, 
  13.               175000); 
  14.     manager.branchManager.authorize(request); 
  15.     request = new PurchaseRequest(3, "AD Campaign”,800000); 
  16.     manager.branchManager.authorize(request); 
  17.   } 
  18.   public void createAuthorizationFlow() { 
  19.     branchManager = new BranchManager("Robin"); 
  20.     regionalDirector = new RegionalDirector("Oscar"); 
  21.     vicePresident = new VicePresident("Kate"); 
  22.     coo = new PresidentCOO("Drew"); 
  23.     branchManager.setNextHandler(regionalDirector); 
  24.     regionalDirector.setNextHandler(vicePresident); 
  25.     vicePresident.setNextHandler(coo); 
  26.   } 
  27. }//End of class 

    当客户端PRManager运行,输出类似下面的结果
Branch Manager Robin has authorized the PR - 1:Office Supplies 
V.P. Kate has authorized the PR - 2:HardWare Procurement 
PR - 3:AD Campaign couldn't be authorized. 
Executive Board needs to be consulted for approval 
reason: Amount too large 
下面是当$150,000购买请求发送给授权链表时的顺序图
 

Figure 21.4: Purchase Request Authorization?Message Flow

附件为原文,请大家指正!
附件:Chapter_21.doc(155K) 

  --相关文章--
· 面向对象编程,我的思想 (2007-04-13)
· 面向对象的思维方式 (2007-04-13)
· 通过Javanbsp;Swing看透MVC设计模式 (2007-04-13)
· 适配器模式(Adapternbsp;Pattern) (2007-04-13)
· 追MM与Java的23种设计模式 (2007-04-13)
· 责任链模式(Chainnbsp;ofnbsp;Responsibility) (2007-04-13)

版权所有©2005-2006 JAVA资源网 渝ICP备05007591号 虚拟主机 | 关于我们 | 联系方式 | 广告业务 | 网站地图 | 友情链接