职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递 该请求,知道有一个对象处理它为止[DP].
在模式结构图中,结合上面的文字,不难想象:Client是和Handler相关的,它构造了Handler对象(main函数作为Client),所以它们之间是关联关系(实现实心箭头);Handler提供接口,ConcreteHandler提供具体的处理请求方法,所以它们之间是继承关系;此外,Handler需要提供SetSuccessor接口,好让每个ConcreteHandler知道自己的后继者。所以,ConcreteHandler和Handler之间有聚合关系:在每个Handler对象中必须提供一个成员,用以保存“后继处理者”的地址(作为protected成员,Handler保存ConcreteHandler;这类似于“雁群”聚合了“大雁”个体一样:在雁群类中,保存了大雁个体对象的地址,作为成员)。
下面看看代码:
#include <iostream> void main() int request=20; request = 30; |
很简单吧?需要注意的是C++里面Handler的构造函数咯!如果不将m_Handler设为0的话,会运行出错(因为里面包含的是一个随机数,not NULL)。
职责链的好处:每个对象只需要保持一个指向其后继者的引用,而不需要保持所有候选接收者的引用;降低了耦合度。我们可以随时增加或修改一个请求的结构,增强给对象指派职责的灵活性。
需要担心的是:一个请求极可能到了链末端都没有得到处理,或者因为没有正确配置而得不到正确的处理[1]!
我们来重构一下加薪流程的代码例子:程序员将请求提交给总监,然后总监提交给管理者……层层上报。管理者类自己聚合自己,也就是要保存一个自己上级的指针,它的子类:经理、总监,负责“申请请求”;这些子类和“申请”类之间是依赖关系:子类虚线实心箭头指向申请类,因为Request作为子类函数的参数。
还是看看下面的实现代码吧:
[1] 试想:A类和B类都处理request==10的情况,A对象在B的前面,那么B就得不到处理机会了;如果实际处理情况更加复杂一些:B处理A一些比A更严格的条件,那我在增添一个B类的时候,还要考虑:我当前设置是否合理?会不会消息还没有传递到B这里,就已经被A处理(拦截)了?这样的结果可不是我想要的呢!