|
|
|
| 您的位置:首页>>设计模式>>责任链模式(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
- class BranchManager {
- static double LIMIT = 25000;
- …
- …
- }//End of class
- class RegionalDirector {
- static double LIMIT = 100000;
- …
- …
- }//End of class
- class VicePresident {
- static double LIMIT = 200000;
- …
- …
- }//End of class
- class PresidentCOO {
- static double LIMIT = 400000;
- …
- …
- }//End of class
让我们定义一个PurchaseRequest类,它代表购买请求。
PurchaseRequest ID:int description:String amount:double getAmount():double
 Figure 21.1: PurchaseRequest Class Representation Listing 21.2: PurchaseRequest Class
- class PurchaseRequest {
- private int ID;
- private String description;
- private double amount;
- public PurchaseRequest(int id, String desc, double amt) {
- ID = id;
- description = desc;
- amount = amt;
- }
- public double getAmount() {
- return amount;
- }
- public String toString() {
- return ID + ":" + description;
- }
- }
一个给定的购买请求(PR)被上面的管理代表所授权或处理。换句话说,代表不同管理层次的四个类都是处理给定购买请求的可能处理者(授权者)。因此,不建议PurchaseRequest实例榜定到任何的一个授权者。通过使用责任链模式(CoR),实现了PurchaseRequest对象和可能授权请求的对象集合之间关联的低耦合。 利用责任链模式(CoR),让我们定义一个抽象类PRHandler,它定义这些可能授权购买请求对象的统一接口。 Listing 21.3: Abstract PRHandler Class
- public abstract class PRHandler {
- private PRHandler nextHandler;
- private String handlerName;
- public PRHandler(String name) {
- handlerName = name;
- }
- public String getName() {
- return handlerName;
- }
- public abstract boolean authorize(PurchaseRequest request);
- public PRHandler getNextHandler() {
- return nextHandler;
- }
- public void setNextHandler(PRHandler handler) {
- nextHandler = handler;
- };
- }

Figure 21.2: Purchase Request Approver Hierarchy 现在,每一个授权者被重新定义为抽象类PRHandler的子类。每一个授权对象把购买请求的金额和它所在的管理层次所授权的金额进行比较,如果请求的金额小于授权的金额,它就可以授权购买,如果大于,它传递购买请求到链表中的下一个授权者。 Listing 21.4: PRHandler Concrete Subclasses
- class BranchManager extends PRHandler {
- static double LIMIT = 25000;
- public BranchManager(String name) {
- super(name);
- }
- public boolean authorize(PurchaseRequest request) {
- double amount = request.getAmount();
- if (amount <= LIMIT) {
- System.out.println(" Branch Manager " + getName() +
- " has authorized the PR − " + request);
- return true;
- } else {
- //forward the request to the next handler
- return getNextHandler().authorize(request);
- }
- }
- }//End of class
- class RegionalDirector extends PRHandler {
- static double LIMIT = 100000;
- public RegionalDirector(String name) {
- super(name);
- }
- public boolean authorize(PurchaseRequest request) {
- double amount = request.getAmount();
- if (amount <= LIMIT) {
- System.out.println(" Regional Director " + getName() +
- " has authorized the PR − " +
- request);
- return true;
- } else {
- //forward the request to the next handler
- return getNextHandler().authorize(request);
- }
- }
- }//End of class
- class VicePresident extends PRHandler {
- static double LIMIT = 200000;
- public VicePresident(String name) {
- super(name);
- }
- public boolean authorize(PurchaseRequest request) {
- double amount = request.getAmount();
- if (amount <= LIMIT) {
- System.out.println(" V.P. " + getName() +
- " has authorized the PR − " + request);
- return true;
- } else {
- //forward the request to the next handler
- return getNextHandler().authorize(request);
- }
- }
- }//End of class
- class PresidentCOO extends PRHandler {
- static double LIMIT = 400000;
- public PresidentCOO(String name) {
- super(name);
- }
- public boolean authorize(PurchaseRequest request) {
- double amount = request.getAmount();
- if (amount <= LIMIT) {
- System.out.println(" President & COO " + getName() +
- " has authorized the PR − " + request);
- return true;
- } else {
- System.out.println("PR − " + request +
- " couldn't be authorized.\n " +
- "Executive Board needs to be " +
- "consulted for approval \n" +
- "reason: Amount too large");
- return false;
- }
- }
- }//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
- public class PRManager {
- private BranchManager branchManager;
- private RegionalDirector regionalDirector;
- private VicePresident vicePresident;
- private PresidentCOO coo;
- public static void main(String[] args) {
- PRManager manager = new PRManager();
- manager.createAuthorizationFlow();
- PurchaseRequest request =
- new PurchaseRequest(1, "Office Supplies”,10000);
- manager.branchManager.authorize(request);
- request = new PurchaseRequest(2, "HardWare Procurement”,
- 175000);
- manager.branchManager.authorize(request);
- request = new PurchaseRequest(3, "AD Campaign”,800000);
- manager.branchManager.authorize(request);
- }
- public void createAuthorizationFlow() {
- branchManager = new BranchManager("Robin");
- regionalDirector = new RegionalDirector("Oscar");
- vicePresident = new VicePresident("Kate");
- coo = new PresidentCOO("Drew");
- branchManager.setNextHandler(regionalDirector);
- regionalDirector.setNextHandler(vicePresident);
- vicePresident.setNextHandler(coo);
- }
- }//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)
|
|
|
| |