首页 > 代码库 > 简明 责任链模式(5.1)

简明 责任链模式(5.1)

学生请假是一个经典的引入责任链模式(Chain of Responsibility pattern)的现实场景。学生通常向辅导员请假,按照请假的天数不同如几节课、几天、一个月、一年等,辅导员可能自己或要请示院党委副书记、书记、学校校长批准。

责任链模式可以称为“推卸”式的代理,多个对象能够处理客户发出的请求,即它们都具有相应的方法如handle()。

责任链模式中,多个处理者对象可以构成一定的数据结构,简单地如单向链表。不论构成什么结构,对于处理者的抽象正如数据结构中常用的结点。结点是自引用的,它含有一个或多个本类型的成员变量。

例程 6 1 简单的责任链
package structure.chain;
public abstract class IHandler{
    private IHandler next;//successor
    public void setNext(IHandler next){
        this.next = next;
    }
    public void handle(int day){
        if (next != null){
            next.handle(day);
        }else{System.out.println("no handler");}
    }
}
package structure.chain;
public class H2 extends IHandler{
    @Override public void handle(int day){
        if (day<=6 && day>=1){//some Condition
            System.out.println("ok"+this.getClass().getName());
        }else{
            super.handle(day);
        }
    }
}
假定辅导员、院党委副书记、书记、学校校长分别为H1、H2、H3和H4。现在先实现H1和H2。测试类的代码:
例程 6-2 测试
package structure.chain;
import tool.God;
public class Student{
    public static void test(int x){
        IHandler h2 =(IHandler)God.create("6-1-1-H2");
        IHandler h1 =(IHandler)God.create("6-1-1-H1");
        h1.setNext(h2);
        h1.handle(x);
    }
}

BlueJ中测试输入1、2、10的输出为:

okstructure.chain.H1

okstructure.chain.H2

no handler


假设学生直接找H2处理,即最后一句为h2.handle(x),输入1为no handler。这是因为程序中处理者构成的是单向链表,可用双向链表解决此问题。也可以h2.setNext(h1)。

责任链模式将一个请求的处理者设计为一个链,链上的每个类都可以处理这个请求,或者将处理责任踢皮球给下家

责任链的“链”表示处理流程的走向,H1、H2、H3和H4本身的具体数据结构可以是单向链、单向环、双向链或树。一个典型的应用,就是处理者形成组合模式的树形结构,而将请求/责任沿着树形结构的某种路径,向上或向下传递。

本例有若干细节需要注意:

l        请求者可以向责任链上任一处理者提出请求。在相应的结构支持下,可以按照处理权限上交的方式、按照分段(权限平行)的方式或向下授权的方式处理。例程中演示了分段的方式,你可以改成上交的方式,规定学生总是找辅导员请假。

l        请求可以被责任链处理或不处理。如果要求“请求在责任链中必须被处理”,可以在抽象类中给出默认处理方案。

l        本例中子类没有指定自己的后续结点。抽象类的next设计private而非其他访问权限,子类除了自己的处理代码,其他就交给super.handle(day)。

 上述注意事项主要针对某些朋友的一些含混认识。通过修改上面的例子,你可以实验一下责任链的若干变体。



简明 责任链模式(5.1)