/** 双分发示例。 我们有各种各样的输入事件:鼠标、键盘、手柄...我们需要在客户端可以 自动地调用对应的事件处理函数,而不需要对输入事件进行if/else分别处理, 不管是客户端还是系统内,因为那样不具扩展性,那么我们怎么将这些具体 的事件传给具体的处理器呢?双分发即可以满足这样的需求。 但是它的缺点很明显:事件处理器必须具有接受所有事件的接口,这样就使得 扩展事件不封闭,因为你必须修改事件处理器的接口;事件具有多个输入点, 这可能会带来维护的问题;暴露过多的接口的做法值得考虑的;在扩展事件的 时候,新扩展的事件必须强制加入重定向功能,这也需要考虑。 双分发是通过两次重定向来找到正确的匹配,两次重定向意味着两次查找。 由此可见,完全消除if/else是不可能的。当你扩展的时候,也就意味着你必 须添加新的else,采用其他合理的设计可以让这种添加行为不影响系统内部。 由此,在这样的情况下,我不推荐使用双分发。 */ class Event; class KeyEvent; class MouseEvent; class CanListenEvent { public: virtual bool processEvent(Event* e){return false;}; virtual bool processEvent(KeyEvent* e){return false;}; virtual bool processEvent(MouseEvent* e){return false;}; }; class Event { public: virtual bool acceptListener(CanListenEvent* lsr) = 0; }; class MouseEvent : public Event { public: virtual bool acceptListener(CanListenEvent* lsr) { return lsr->processEvent(this); } }; class KeyEvent : public Event { public: virtual bool acceptListener(CanListenEvent* lsr) { return lsr->processEvent(this); } }; class InputDevice { public: bool sendEvent(Event* e, CanListenEvent* lr) { return e->acceptListener(lr); } }; class KeyListener : public CanListenEvent { public: virtual bool processEvent(KeyEvent* e) { return true; } }; class MouseListener : public CanListenEvent { public: virtual bool processEvent(MouseEvent* e) { return true; } }; #include <assert.h> class DoubleDispatchTest { public: DoubleDispatchTest() { MouseEvent me; KeyEvent ke; InputDevice id; // can send kinds of events to specify listener KeyListener keyLsr; // care about key event only. MouseListener mouseLsr; // care about mouse event only assert(id.sendEvent(&me, &keyLsr)==false); assert(id.sendEvent(&me, &mouseLsr)==true); assert(id.sendEvent(&ke, &keyLsr)==true); assert(id.sendEvent(&ke, &mouseLsr)==false); } }; void main() { DoubleDispatchTest test; }