[学习笔记]设计模式之Chain of Responsibility(二)

2014-11-24 00:41:44 · 作者: · 浏览: 1
handleRequest首先会检测自己是否具备该能力,如果没有的话,它将把这个请求转发给后继者。同理,我们有非常类似的HobbitWoodCutter类:
复制代码
1 class HobbitWoodCutter : public Hobbit {
2 protected:
3 HobbitWoodCutter(Hobbit* h, int a = ABILITY_CARP);
4
5 virtual void handleRequest(int);
6 }
7
8 HobbitWoodCutter::HobbitWoodCutter(Hobbit* h, int a):Hobbit(h, a) {}
9
10 HobbitWoodCutter::handleRequest(int a) {
11 if (hasAbility(a)) {
12 // handle this request.
13 } else {
14 Hobbit::handleRequest(a);
15 }
16 }
复制代码
同理还有HobbitWise类等等,下面我们就创建并连接这些对象以演示前言部分的例子:
1 HobbitWoodCutter* theWoodCutter = new HobbitWoodCutter(0);
2 HobbitWarrior* theWarrior = new HobbitWarrior(theWoodCutter);
3 HobbitWise* theWise = new HobbitWise(theWarrior);
然后白雪公主找到theWise,向他请求一个木工活:
theWise->handleRequest(ABILITY_CARP);
后面发生的事,大家就都知道了。对应于这个例子的UML图如下:
特点总结
从例子我们可以看出,白雪公主无需知道小霍比特人之间的联系,她只需要知道,她的请求会得到应有的响应(除了完成请求之外,当然也有可能大家都完不成这个请求)。
用专业的术语表示,职责链模式具有如下优缺点:
降低耦合度。该模式使得一个对象无需知道是其他哪一个对象处理其请求。接收者和发送者都没有对方的明确的信息,且链中的对象不需知道链的结构。这样一来,职责链简化了对象的相互连接。它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
增强了给对象指派职责Responsibility的灵活性。我们可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责,这给我们更大的灵活性。
缺点就是不保证被处理。既然一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理。一个请求也可能因该链没有被正确配置而得不到处理。
职责链模式是一个看起来简单,但是却容易被误解的模式。最常见的误区就是上下级关系这块。事实上职责链并没有严格的上下级关系,只是保持一个对后继者的引用而已。后继者可以是它父类的对象,也可以是同级的对象。