0

在我的场景中,我有组件 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
    }
};

组件 A 使用 MessageA 编译

组件 B 使用 MessageA 编译

所以说,当组件 A 想要向组件 B 发送消息时,它会实例化一个 MessageA 对象,prepare() 并将其发送出去。当组件 B 通过套接字接收到消息时,它会解析()它并处理()它。

我现在的问题在于 handle() 函数。只有消息的接收者会调用 handle() 函数。handle() 函数的实现需要执行某些例程,这些例程涉及接收组件中的函数。

我现在可以像这样使用 PREPROCESSOR 来解决这个问题:

void handle() {
#ifdef COMPILE_FOR_COMPONENT_A
componentA->executeFunctionABC();
#endif
}

但它看起来很丑。我想知道是否有任何设计模式可以正确地做到这一点?

4

3 回答 3

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

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();
  }
}

您仍然会得到组件的接口,但您只有与消息一样多的方法。这实际上是您的预处理器指令所实现的。

于 2012-07-23T02:44:51.167 回答
0

您能否将 Message 本身与诸如处理、解析和准备等消息操作分开?

尝试从 MessageHandler、MessageParser 和 MessagePreparer 的角度思考。他们可以使用通用消息接口的哪些部分来访问消息的数据?会有什么不同?

如果成功,组件 A 将需要 MessageA_Preparer 和 MessageB_Handler 和 _Parser。组件 B 将需要 MessageB_Preparer 和 MessageB_Handler 和 _Parser。

于 2012-07-23T03:10:52.250 回答
0

这不是对您处理 handle() 函数的现有问题的答案,而只是想问您(因为我也对这种机制感兴趣)为什么让消息执行 prepare()、parse() 和 handle( )? 我觉得应该有一个应该处理prepare()的发送者类和一个应该处理parse()的接收者类,并且取决于你实现handle()的方式,也许也是如此。

如果 Message 类只包含消息,而发送者和接收者类处理其他功能不是更好吗?

于 2012-07-23T04:18:30.360 回答