在我的场景中,我有组件A和组件B,它通过Message类进行通信。
我的消息类看起来像这样
class Message {
virtual void prepare();
virtual void parse();
virtual void handle();
};
任何消息都是Message类的子类,例如:
class MessageA: public Message {
void prepare() {
...
}
void parse() {
...
}
void handle() {
componentA->executeFunctionABC(); // componentA is a global pointer
}
};
使用MessageA
编译组件A.组件B使用MessageA
编译因此,当组件A想要向组件B发送消息时,它将实例化一个MessageA对象,prepare()并将其发送出去。当组件B通过套接字接收消息时,它将解析()它并处理()它。
我现在的问题在于handle()函数。只有消息的接收者才会调用handle()函数。 handle()函数的实现需要执行某些涉及接收组件中的函数的例程。
我现在可以使用这样的PREPROCESSOR来解决这个问题:
void handle() {
#ifdef COMPILE_FOR_COMPONENT_A
componentA->executeFunctionABC();
#endif
}
但它看起来很难看。我想知道是否有任何设计模式可以正确地做到这一点?
答案 0 :(得分:0)
如果您的组件实现了通用接口,则可以将组件传递到handle
方法:
class Component {
virtual void executeFunctionABC() = 0;
virtual void executeFunctionDEF() = 0;
}
class MessageA : public Message {
void handle(Component *c) {
c->executeFunctionABC();
}
}
当组件收到消息时,它会调用:
message->handle(this);
此外,根据您的说明,prepare
和parse
似乎主要用于创建/恢复邮件,因此我会将它们作为工厂方法(Message
中的静态方法或单独的MessageFactory
类)而不是Message
类上的虚拟方法。
修改或者,您可以通过为每个组件使用单独的handle
方法来使用visitor pattern:
class MessageA : public Message {
void handle(ComponentA *c) {
c->executeFunctionABC();
}
void handle(ComponentB *c) {
...
}
}
如果您有一些功能非常不同的组件,这种方法很有效。如果您具有具有类似功能的组件,则接口方法很有效。
编辑2 :要完全解耦组件,您可以使用前两种解决方案的混合:
class MessageHandler {
virtual void handle(MessageA *msg) = 0;
virtual void handle(MessageB *msg) = 0;
}
class MessageA : public Message {
void handle(MessageHandler *handler) {
handler->handle(this);
}
}
class ComponentA : public MessageHandler {
void handle(MessageA *msg) {
executeFunctionABC();
}
}
您仍然可以获得组件的接口,但您只有与消息一样多的方法。这实际上是您的预处理器指令实现的目的。
答案 1 :(得分:0)
您是否可以将Message与处理,解析和准备等消息的操作分开?
尝试使用MessageHandler,MessageParser和MessagePreparer。他们可以使用哪些常见的Message接口来访问消息的数据?会有什么不同?
如果这样做,组件A将需要MessageA_Preparer和MessageB_Handler以及_Parser。组件B将需要MessageB_Preparer和MessageB_Handler以及_Parser。
答案 2 :(得分:0)
这不是你现有处理handle()函数问题的答案,但只是想问你(因为我也对这种机制感兴趣)为什么你让消息执行prepare(),parse()和handle()?我觉得应该有一个发送者类应该处理prepare()和一个接收器类,它应该处理parse(),并且取决于你实现handle()的方式,也许也是如此。
如果Message类只包含消息,发送方和接收方类处理其他功能会不会更好?