顿搜
责任链模式(Chain of Responsibility)——23种设计模式之行为型模式
在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显式指定,将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者? 让请求的接受者自己在运行时决定来处理请求, 从而使二者解藕。
使多个对象都有机会处理请求,从而避免请求的发送 者和接收者之间的耦合关系。将这些对象连成一条链, 并沿着这条链传递该请求,直到有一个对象处理它为止。
职责链可以是一条直线、一个环或者一个树形结构, 最常见的职责链是直线型,即沿着一条单向的链来传递请求。链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递, 由链上的处理者对请求进行相应的处理,客户端无须 关心请求的处理细节以及请求的传递,只需将请求发 送到链上即可,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。将请求的发送者和请求的处理者解耦。 这就是职责链模式的模式动机。
一、类图表示
责任链模式涉及到Handler,ConcreteHandler,Client三个角色
①、Handler:定义一个处理请求的接口(可选)实现后继链
②、ConcreteHandler:处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之;否则将该请求转发给它的后继者
③、Client:提交请求。
二、代码示例
public abstract class Handler {
/**
* 持有后继的责任对象
*/
protected Handler successor;
/**
* 示意处理请求的方法,虽然这个示意方法是没有传入参数的
* 但实际是可以传入参数的,根据具体需要来选择是否传递参数
*/
public abstract void handleRequest();
/**
* 取值方法
*/
public Handler getSuccessor() {
return successor;
}
/**
* 赋值方法,设置后继的责任对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}public class ConcreteHandler extends Handler {
/**
* 处理方法,调用此方法处理请求
*/
@Override
public void handleRequest() {
/**
* 判断是否有后继的责任对象
* 如果有,就转发请求给后继的责任对象
* 如果没有,则处理请求
*/
if(getSuccessor() != null){
System.out.println("放过请求");
getSuccessor().handleRequest();
}else{
System.out.println("处理请求");
}
}
}public class Client {
public static void main(String[] args) {
//组装责任链
Handler handler1 = new ConcreteHandler();
Handler handler2 = new ConcreteHandler();
handler1.setSuccessor(handler2);
//提交请求
handler1.handleRequest();
}
}三、责任链类型
纯的与不纯的责任链模式
1、纯的责任链:
一个纯的责任链模式要求一个具体的处理者对象只能 在两个行为中选择一个:一个是承担责任,二是把责 任推给下家。不允许出现某一个具体处理者对象在承 担了一部分责任后又把责任向下传的情况。
2、不纯的责任链
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收,在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。纯的责任链模式的例子不多见,一般的例子均是不纯的责 任链模式的实现。
四、责任链的灵活
1、 改变内部的传递规则
- ①、在内部,完全可以跳过好几个责任链上的节点。
- ②、每个人都可以去动态地指定他的继任者
2、可以从职责链任何一关开始
五、优缺点分析
1、优点
- ①、降低耦合度:对象仅需知道请求会被“正确”地处理。接收者和发送者都没有对方的明确信息。
- ②、增强了给对象指派职责的灵活性
2、缺点
- ①、当这个链结构比较长,比较复杂的话,会产生很多的内存垃圾对象。
- ②、而传递工作之后,他们就成了垃圾对象。
- ③、不保证被接受
六、模式间关系
1、与组合模式的关系
- ①、经常与Composite一起使用。这时,一个构件的父构件可作为它的后继。
七、适用场景
某些对象请求的接受者可能多种多样,变化无 常
- ①、有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
- ②、想在不明确接收者的情况下,向多个对象中的一个提交一个请求。
- ③、可处理一个请求的对象集合应被动态指定。
八、总结
职责链是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。
- ①、职责链 ≠链表,职责链节点中的任何一个节点作为开始节点,这就是链表与职责链不同的地方。
- ②、每一个节点都可以使用一个List来维护它的下一节点,甚至可以用组合模式来分别设计每一节点
- ③、应该为职责链设置一个默认的条款,称为兜底条款
- ④、将对象连成一条链,并沿着这条链传递该请求,直到有一个对 象处理他为止。
- ⑤、有多个对象可以处理一个请求,哪个对象处理该请求则在运行时刻确定。
- ⑥、在不明确指定接收者的情况下,向多个对象中的一个提交请求,可处理请求的对象集合应被动态制定。
- ⑦、责任链模式并不创建责任链。责任链的创建必须由系统的其它部分创建出来。
