CHAIN OF RESPONSIBILITY责任链
1、 意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿用这条链传递该请求,直到有一个对象处理它为止。
2、 适用性
在以下条件下使用responsibility链:
- 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
- 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可处理一个请求的对象集合应被动态指定。
3、 结构
4、 参与者
- Handler
——定义一个处理请求的接口。
——(可选)实现后继链。
- ConcreteHandler
——处理它所负责的请求。
——可访问它的后继者。
——如果可处理该请求,就处理之;否则将该请求转发给它的后继者。
- Client
——向链上的具体处理者对象提供请求。
5、 协作
当客户提交一个请求时,请求沿链传递直至有一个ConcreteHandler对象负责处理它。
6、 效果
Responsibility链有下列优点和缺点:
1) 降低耦合度;该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求被“正确”地处理。接收者和发送者都没有对方的明确的信息,且链中的对象不知道链的结构。结果是,责任链可简化对象的互相连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接收者的引用。
2) 增强了给对象指派职责的灵活性;当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。
3) 不保证被接受;一个对象没有明确的接收者,那么就不能保证它一定会被处理。该请求可能一直到链末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。
7、 实现
下面是在职责链模式中要考虑的实现问题:
1) 实现后继者链;有两种方法可以实现后继链。
a) 定义新的链接(通常在Handler中定义,但也可由ConcreteHandler来定义)。
b) 使用已有的链接。
2) 连接后继者。如果没有已有的引用可定义一个链,那么你必须自己引入它们。这种情况下Handler不仅定义该请求的接口,通常也维护后继链接。这样Handler就提供了HandleRequest的缺省实现:HandleRequest向后继者转发请求。如果ConcreteHandler子类该请求不感兴趣,它不需要重定义转发操作,因为它的缺省实现进行无条件的转发。
3) 表示请求。可以有不同的方法表示请求。
8、 代码示例
Handler
package com.examples.pattern.responsibility;
/**
* 职责的接口,也就是处理请求的接口
*/
public abstract class Handler {
/**
* 持有后继的职责对象
*/
protected Handler successor;
/**
* 设置后继的职责对象
* @param successor 后继的职责对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
/**
* 处理方法
*/
public abstract void handleRequest();
}
ConcreteHandler
package com.examples.pattern.responsibility;
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest() {
//根据某些条件判断是否属于自己处理的职责范围
boolean someCindition = false;
if(someCindition){ //如果是自己的职责范围
System.out.println("ConcreteHandler1 handle request");
}else{ //不是自己的职责范围
if(this.successor != null){ //判断是否有后继的职责对象。如果有,就转发请求给后继者
this.successor.handleRequest();
}
}
}
}
package com.examples.pattern.responsibility;
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest() {
//根据某些条件判断是否属于自己处理的职责范围
boolean someCindition = true;
if(someCindition){ //如果是自己的职责范围
System.out.println("ConcreteHandler2 handle request");
}else{ //不是自己的职责范围
if(this.successor != null){ //判断是否有后继的职责对象。如果有,就转发请求给后继者
this.successor.handleRequest();
}
}
}
}
Client
package com.examples.pattern.responsibility;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
//先要组装职责链
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
h1.setSuccessor(h2);
//提交请求
h1.handleRequest();
}
}
9、 相关模式
责任链通常与Composite一起使用,这种情况下,一个构建的父构件可作为它的后继。