责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
责任链可能是一条直线、一个环链或者一个树结构的一部分。
一,结构:
抽象处理者(Handler)角色: 定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。
具体处理者(ConcreteHandler)角色: 具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
二,示例代码
/** * 抽象处理者(Handler)角色 * @author Salmon * */ public abstract class Handler { protected Handler successor; //设置下家 public void setSuccessor(Handler successor) { this.successor = successor; } //处理方法 public abstract void handleRequest(int request); } /** * 具体处理者(ConcreteHandler)角色 * @author Salmon * */ public class ConcreteHandler1 extends Handler { public void handleRequest(int request) { if (request >= 0 && request < 10) System.out.println("handler by ConcreteHandler1"); else if (successor != null) successor.handleRequest(request); //交给下家处理 } } /** * 具体处理者(ConcreteHandler)角色 * @author Salmon * */ public class ConcreteHandler2 extends Handler { public void HandleRequest(int request) { if (request >= 10 && request < 20) System.out.println("handler by ConcreteHandler2"); else if (successor != null) successor.handleRequest(request); //交给下家处理 } } /** * 客户程序 * @author Salmon * */ public class Client { public static void main(String[] args) { Handler h1 = new ConcreteHandler1(); Handler h2 = new ConcreteHandler2(); h1.setSuccessor(h2); h2.setSuccessor(null); //形成链 int[] requests = { 2, 5, 14, 18, 3 }; for (int request : requests) h1.handleRequest(request); } }
三,纯与不纯的职责链模式
一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一个是承担责任,二是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。纯的责任链模式的例子是不容易找到的,一般看到的例子均是不纯的责任链模式的实现。