Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 封装与封装;消息对象_C++_Message Queue_Encapsulation_Observer Pattern_Mediator - Fatal编程技术网

C++ 封装与封装;消息对象

C++ 封装与封装;消息对象,c++,message-queue,encapsulation,observer-pattern,mediator,C++,Message Queue,Encapsulation,Observer Pattern,Mediator,在开发内部消息系统(如通过中介或观察者模式)时,封装传递的消息对象的最佳方式是什么 考虑以下消息对象,它告诉某些服务运行新的作业。该消息包含需要运行的作业 #define MESSAGE_JOB = 1 class NewJobMessage: public Message { virtual int getType() { return MESSAGE_JOB; } Job* m_Job; } 现在,可以在服务的以下handleMessage功能中处理该消息: bool Jo

在开发内部消息系统(如通过中介或观察者模式)时,封装传递的消息对象的最佳方式是什么

考虑以下消息对象,它告诉某些服务运行新的
作业
。该消息包含需要运行的
作业

#define MESSAGE_JOB = 1
class NewJobMessage: public Message
{
    virtual int getType() { return MESSAGE_JOB; }
    Job* m_Job;
}
现在,可以在服务的以下
handleMessage
功能中处理该消息:

bool JobService::handleMessage( Message* msg )
{
    switch( msg.getType() )
    {
    case MESSAGE_JOB:
        runJob( (dynamic_cast<NewJobMessage*>( msg ))->m_Job );
        return true;
    case default:
        return false;
    }
}
booljobservice::handleMessage(Message*msg)
{
开关(msg.getType())
{
案例消息\u作业:
runJob((dynamic_cast(msg))->m_Job);
返回true;
案例默认值:
返回false;
}
}
这看起来很好,但NewJobMessage必须了解Job类,即使它从未以任何有意义的方式使用它;只是运输而已


是否更倾向于采用其他方式来避免消息与数据耦合?我曾想过使用一个
void*
并将其强制转换,但如果有其他人来剖析我的代码,这似乎有点骇人听闻,可能会让人困惑。

这是一个教科书式的案例,说明
void*
是合适的。
void*
的真正缺点是运行时类型检查,但是您的
getType()
方法是一个很好的例子,表明您已经陷入了困境

要使其不协调,只需保持结构简单即可

// No need to inherit from this.
struct Message {
  int type;
  void * data;
};

只要您以一种有组织的方式编写代码,这就不会造成混淆,非类型化的数据是最重要的。

您没有提到这些消息是如何传递的,或者它们可能会传递多远(通过网络?),但总的来说,我强烈建议不要传递本机对象。这是一个痛苦的食谱和痛苦的道路。这是一个维护和调试噩梦,一个安全攻击向量,设计耦合问题,并且只有当这个系统稍后扩展时才会变得更糟(因为它总是这样)。 因此,有几种方法可以解决这个问题:

  • 使用CDR或类似的方式对信息进行编码,以对作业信息进行编码。接收器反转CDR以获取信息,即使它不是相同的语言、系统或字节大小/顺序。编写代码有点乏味,但在计算或空间方面并不昂贵
  • 根据您的偏好和经验以及数据中的信息类型,将请求打包到更高级别,如JSON或XML。在第三方库的帮助下,这通常是相当容易的,但是转换文本和传输文本的成本要高一些。诊断问题和调查运输过程中的情况也要容易得多

在其他条件相同的情况下,我倾向于使用JSON,除非您需要处理和传输这些请求的速度太快,您的处理速度跟不上。使用现代C++库来处理JSON。< /P>在代码> >返回< /Cord>语句:“代码>虚拟int GETType()){返回MeaseGeJoo};} /Cord>这一切都在同一进程内部处理,这应该相当容易。我只是想解耦系统的各个组件,以及它们通过这些消息命令进行通信的内容。序列化并不是我想要的,但是我可以想到我需要它的其他地方;谢谢我认为
getType()
现在有点多余,因为我有一条消息需要发送两个指针,我应该从这个结构继承吗?或者是双重间接的,让
void*data
指向包含两个指针的结构是的,您将让
void*data
指向包含两个指针的结构。如果这种情况困扰您,您可以将另一个指针结构添加到
struct Message
。实际上,您可以向其中添加任何内容(windows MSG结构包含时间戳、光标的x/y、发送消息的窗口的标识符和两个通用指针/整数)。总是会有一个折衷,因为有些消息不需要额外的字段,而其他消息则需要一定程度的间接寻址来支持额外的字段。
getType()
并不是多余的。消息队列消息基本上需要包含其数据以及如何处理该数据的一些指示符。类型信息表示如何处理数据。
void*
表示数据。消息不应包含需要运行的作业。该消息表示需要运行的作业。在消息队列中传递消息对于一个线程调用另一个线程中的函数来说是非常困难的。类型是函数名。数据是函数参数。我有一个组件负责运行作业,因此消息的数据就是作业。谢谢您的回答为这方面的最佳方法提供了很多信息。例如,查看windows消息传递API可能会有所帮助。我觉得这一页很有帮助,尽管它依赖于一些windows API技术。