使多个对象都有机会处理请求,从而避免请求的发送者和接收者的耦合关系,将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理了它为止。
Chain of Responsibility模式中ConcreteHandler将自己的后继对象(向下传递消息的对象)记录在自己的后继表中,通过这样的连接,将可能处理一个请求的对象链接成一个链,当一个请求到来时,ConcreteHandler会先检查看自己有没有匹配的处理程序,如果有就自己处理,否则传递给它的后继。这使得发出这个请求的客户端并不需要知道链上的哪一个对象最终处理这个请求,避免了请求的发出者与接收者之间的高耦合,客户端只需组织其责任链,并且设置请求,并可以动态地重新组织和分配责任。
参与者:
- 抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对后继对象的引用。这个角色通常由一个抽象类或接口实现。
- 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给后继对象。由于具体处理者持有对后继对象的引用,因此,如果需要,具体处理者可以访问后继对象。
优点:
- 责任链模式降低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。
- 由于是在客户端来定义责任链的结构,可以动态地增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。
缺点:
- 责任链模式一般是从链子的开头位置进行遍历,找到时候的处理对象,对性能有一定的损耗。
适用场合:
- 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
- 想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可处理一个请求的对象集合应被动态指定。
- 当一个方法的传入参数将成为分支语句的判断条件,分支条件存在扩展的可能,每一个分支的职责相对独立,且逻辑较为复杂时。
与状态模式的区别:
- 责任链模式注重责任的传递,并且责任链由客户端进行配置,具体的操作对象维护了一下后继者的引用(由客户端配置),如果自己能够处理,则处理,不能处理调用后继者处理。
- 状态模式注重对象状态的转换,这个转换过程对客户端是透明的。重点是把状态的判断逻辑封装在“表示不同状态的一系列类中”具体的操作完成后,修改被操作这的状态,这个状态的修改对客户端是透明的。
纯责任链模规定一个具体的处理对象只能对请求作出处理请求或传给后继者两种动作,不能出现处理了一部分,把剩下的传给后继者处理的情况,而且请求在责任链中必须被处理。然而责任链模的思想在于,通过将多个处理对象建立关联,来达到请求与具体的某个处理者的解耦。所以在实际的需求中不一定非要达到一种纯责任链模式的设计。
责任链模式并不创建责任链。责任链的创建必须由系统的其它部分创建出来。
责任链可以是一个链可以是一条线,一个树,也可以是一个环。
GoF规定一个请求必须被某一个处理者对象所处理,所以为了避免一个请求有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,可以提供一个默认处理所有请求的对象。
参考资料:
设计模式学习总结-责任链模式(Chain of Responsibility Method)