一个用C++实现的Dispatcher(一)

标签: dispatcher | 发表时间:2010-09-09 23:04 | 作者:dreamhead kevH
出处:http://dreamhead.blogbus.com

又和一个团队合作,面前又摆着一堆分发的代码,不同的是,这次用的是C++:
if (msg->id == "open") {
    MsgHandler handler(msg);
    handler.open();
} else if (msg->id == "close") {
    MsgHandler handler(msg);
    handler.close();
} else if (…) {
    …
} else {
    // exception handler
    …
}

不要问我为什么不是每个消息对应一种处理类,要是知道为什么,就不是遗留代码了。于是,我们尝试着用C++写了一个dispatcher。下面是这个dispatcher的声明:
#include <map>

typedef void (MsgHandler::*handlerFunc)();

class MsgDispatcher {
public:
    ...
    void dispatch(Msg* msg);
private:
    std::map<string, handlerFunc> handlers;
};

因为要处理遗留代码,这里用到了指向成员函数的指针,也就提高了理解这段代码的门槛。具体实现如下:
void MsgDispatcher::dispatch(Msg* msg) {
    handlerFunc func = this->handlers[msg->id];
    if (func) {
        MsgHandler msgHandler(pkg);
        (msgHandler.*func)();
    } else {
        // exception handler
        …
    }
}

注册很简单:
handlers["open"] = &MsgHandler::open;
handlers["close"] = &MsgHandler::close;

相关 [dispatcher] 推荐:

一个用C++实现的Dispatcher(一)

- kevH - 梦想风暴
又和一个团队合作,面前又摆着一堆分发的代码,不同的是,这次用的是C++:. 不要问我为什么不是每个消息对应一种处理类,要是知道为什么,就不是遗留代码了. 于是,我们尝试着用C++写了一个dispatcher. 下面是这个dispatcher的声明:. 因为要处理遗留代码,这里用到了指向成员函数的指针,也就提高了理解这段代码的门槛.

一个用C++实现的Dispatcher(二)

- kevH - 梦想风暴
遗留代码就是遗留代码,总会有一些让人意想不到的地方,原以为所有消息都是由一个类(MsgHandler)处理的,可事实上,不是. 上面的代码里面只有消息处理类的名字不同,其它的处理完全相同. 不过,这样就让之前那个dispatcher就显得势单力薄. 解决程序设计的问题,有一个很好用的处理手法:加个间接层.

一个用C++实现的Dispatcher(三)

- kevH - 梦想风暴
eBen给《一个用C++实现的Dispatcher(二)》提出了一些非常好的问题,修正了一些细节. 那几个new,可能某些做服务器端程序的人会受不了. handlers倒是可以做成static的.所有对象共用一份就可以了. 这个问题在实现这个dispatcher的时候,有人提出来过,但我依然坚持我的选择.