一、概念
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
(1)在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
(2)请求在这条链上传递,直到链上的某一个对象处理此请求为止。
(3)发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
二、两个角色
Handler(抽象处理者):
它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(如结构图中的successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。ConcreteHandler(具体处理者):
它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。Client(客户类):
向一个链上的具体处理者ConcreteHandler对象提交请求
需要注意的是,职责链组装(即设置后续handler)一般在Client中完成。职责链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。
三、结构图
?
四、代码实现
abstract class Handler {
//维持对下家的引用
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor=successor;
}
public abstract void handleRequest(String request);
}
class ConcreteHandler extends Handler {
public void handleRequest(String request) {
if (请求满足条件) {
//处理请求
}
else {
this.successor.handleRequest(request); //转发请求
}
}
}
五、小结
1、优点
(1)降低耦合度
该模式使得一个对象无需知道是其他哪一个对象处理其请求。对象仅需知道该请求会被“正确”地处理。接收者和发送者都没有对方的明确的信息,且链中的对象不需知道链的结构。
(2)职责链可简化对象的相互连接
职责链可简化对象的相互连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
(3)增强了给对象指派职责的灵活性
当在对象中分派职责时,职责链给你更多的灵活性。你可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责。你可以将这种机制与静态的特例化处理对象的继承机制结合起来使用。
(4)增加新的请求处理类很方便
2、缺点
(1)不能保证请求一定正确处理
既然一个请求没有明确的接收者,那么就不能保证它一定会被处理 —该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。
备注:在我看来这条前一半逻辑不成立,完全可以保证有一个最后的接收者。但是后一半还是可以说得通的,配置错了你搞笑呢,请求当然处理不了了。
(2)系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
六、职责链模式分类
1、纯的职责链模式
一个具体处理者角色处理只能对请求作出两种行为中的一个:一个是自己处理(承担责任),另一个是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又将责任向下传的情况。请求在责任链中必须被处理,不能出现无果而终的结局。
2、不纯的职责链模式。
在一个纯的职责链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的职责链模式里面,一个请求可以最终不被任何接收端对象所接收。