首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

【设计形式攻略】行为型模式之Chain of Responsibility模式

2013-10-27 
【设计模式攻略】行为型模式之Chain of Responsibility模式概要程序中经常出现这样的逻辑,收到XX请求,进行XX

【设计模式攻略】行为型模式之Chain of Responsibility模式
概要程序中经常出现这样的逻辑,收到XX请求,进行XX相关的响应处理,收到YY请求,则进行YY的响应处理。请求与响应之间彼此配对,所以代码也往往会为这种配对提供一对一的对应关系。比如说之前说过的Command模式中,一种Command会跟一个Performer对应起来确保这种逻辑关系。那如果某个请求该如何响应是未知或动态决定的,如何处理呢?答案之一,用一堆条件来判断限制啊?很多情况下,没错,应该这样做。但有时这样做会不会太累啊?有没有什么其他方案呢?Chain of Responsibility模式就是选择之一,通过对所有的响应方建立职责链,请求方不需要知道由哪个响应来执行,只需要把请求丢给职责链,职责链的每个元素都有可以执行,可以传递,当然也可以中止传递。
目的避免请求方耦合于执行方,请求方可以不需要知道哪个目标会执行该请求,而只需要把请求传递给职责链就ok。执行方被动态串联形成职责链,执行条件由每个元素自己控制。
实例想到这样一个伪例子,当收到的命令小于Command1或者等于Command3时,执行Performer1,当命令大于Command1,小于Command5并且不等于Command3时,执行Performer2,当命令等于Command7时,也执行Performer2,当命令大于Command5,小于Command9并且不等于Command7时,执行Performer3。好纠结的条件啊,其实代码倒还好,看下实现:



太抽象了,还是直接看下代码怎么实现的,首先Handler类提供handle_request接口,并提供set_successor方法可以设置职责链上下一个Handler是谁,每个具体的Handler子类实现自己的handle_request,其中关注某个performer运行需要的条件就可以了,当然也别忘了在不符合条件时把cmd传给下一个Handler。
class Handler {public:       void handle_request(int cmd) {             if (handle_request_impl(cmd) == false && m_successor != NULL) {                  m_successor->handle_request(cmd);            }      }       virtual bool handle_request_impl(int cmd) = 0;       public void set_successor(Handler* successor)      {            m_successor = successor;      }private:      Handler* m_successor;};class ConcreteHandler1 : public Handler {public:       bool handle_request_impl(int cmd) {             if (cmd <= COMMAND_1 || cmd == COMMAND_3) {                  perform1.action();                   return true ;            }             return false ;      }};class ConcreteHandler2 : public Handler {public:       bool handle_request_impl(int cmd) {             if (cmd <= COMMAND_5 || cmd == COMMAND_7) {                  perform2.action();                   return true ;            }             return false ;      }};class ConcreteHandler3 : public Handler {public:       bool handle_request_impl(int cmd) {             if (cmd <= COMMAND_9) {                  perform3.action();                   return true ;            }             return false ;      }};

应用除了以上示例中的例子,实际应用中有时还希望一个请求可能被多个Handler处理的情况,针对这种情况其实只要稍微修改下代码,控制handle_request_impl的返回值就可以做到。另外,如果不需要由调用方来调用set_successor组成职责链,那么甚至可以在每创建一个Handler时自动进入职责链,从而把set_successor的细节也隐藏掉,如何实现的话,自己尝试吧。

热点排行