消息机制简单实现模块间解耦

来源:互联网 发布:u型耳夹淘宝 编辑:程序博客网 时间:2024/06/08 09:24

消息机制一直是软件开发中减少模块之间耦合的标准方式,下面我们举一个简单的例子,看看是如何通过消息,减少类 A 和类 B之间的耦合度的。


下面是传统的方法,实现 A 对 B 类的某个方法的调用,不使用消息机制的传统方法,A 需要持有 B 的对象,并且 A 要知道所要调用的B的方法,这样 A 和 B 就强耦合在了一起,一旦 B 类发生变化,A 类就可能要重新编译,而且如果 doSomethingBSpecial 这个方法需要改名,或者修改参数,A 类就也需要修改,这样的依赖关系就带来了诸多的不便。

  1. #include “stdafx.h”
  2. #include <vector>
  3. #include <iostream>
  4. class B
  5. {
  6. public:
  7.     void doSomethingBSpecial()
  8.     {
  9.         //B 做一些事情
  10.         std::cout << “B do something…” << std::endl;
  11.     }
  12. };
  13. class A
  14. {
  15. public:
  16.     A(B* b) :m_b(b){}
  17.     void doSomethingASpecial()
  18.     {
  19.         //在这个方法中,会调用B 的 doSomethingBSpecial
  20.         m_b->doSomethingBSpecial();
  21.     }
  22. private:
  23.     B* m_b;
  24. };
  25. int _tmain(int argc, _TCHAR* argv[])
  26. {
  27.     A a(new B());
  28.     a.doSomethingASpecial();
  29.     return 0;
  30. }

    下面使用消息机制实现同样的调用,这样 A 就不需要引用 B 的对象,同时 A 也不需要知道 B 的方法,实现了 A 类 和 B 类的解耦。

    下面简易的实现了一个的消息处理器,只具备简易的注册,删除和触发事件的功能,在客户的代码中,把 B 的对象注册到消息处理器,使 B 可以处理 doSomethingASpecial 这个消息,然后在 A 类需要调用 B 的方法的地方, 可以直接用消息处理器处理 doSomethingASpecial 这个消息,MsgMgr::handle(“doSomethingASpecial”) 这样调用以后,所有注册过 doSomethingASpecial 这个消息的对象(包括 B 对象),都会接受并且处理这个消息,B 对象的 handle 方法就会被调用,然后在这个方法里就可以去调用 B 的 doSomethingBSpecial 方法,这样就实现了 A 对 B类的 doSomethingBSpecial 方法的调用, 去掉了 A 和 B 之间的耦合依赖关系。


    1. #include “stdafx.h”
    2. #include <vector>
    3. #include <iostream>
    4. #include <map>
    5. #include <string>
    6. //使用消息机制,A 就不需要持有 B 的对象,
    7. //消息接受者接口
    8. class MsgReceiver
    9. {
    10. public:
    11.     virtual void handle() = 0;
    12. };
    13. //这里实现一个简易的消息处理器,只具备简易的,注册,删除,和触发事件的功能
    14. static std::map<std::string, MsgReceiver*> m_allMsgRecevers;
    15. class MsgMgr
    16. {
    17. public:
    18.     static void addReceiver(std::string msg, MsgReceiver* receiver)
    19.     {
    20.        m_allMsgRecevers.emplace(msg, receiver);
    21.     }
    22.     static void removeReceiver(std::string msg)
    23.     {
    24.        m_allMsgRecevers.erase(msg);
    25.     }
    26.     static void handle(std::string msg)
    27.     {
    28.         m_allMsgRecevers.at(msg)->handle();
    29.     }
    30. };
    31. class A
    32. {
    33. public:
    34.     void doSomethingASpecial()
    35.     {
    36.         //这里如果想调用 B 的 doSomethingBSpecial 方法
    37.         //可以直接用消息处理器处理 doSomethingASpecial 这个消息
    38.         //因为 B 已经注册声明过可以处理 doSomethingASpecial 这个消息
    39.         //MsgMgr::handle(“doSomethingASpecial”) 这样调用以后,所有
    40.         //注册过 doSomethingASpecial 这个消息的对象,都会接受并且处理这个消息
    41.         //这样就去掉了A 和 B之间的耦合依赖关系
    42.         MsgMgr::handle(“doSomethingASpecial”);
    43.     }
    44. };
    45. class B : public MsgReceiver
    46. {
    47. public:
    48.     void doSomethingBSpecial()
    49.     {
    50.         //B 做一些事情
    51.         std::cout << “B do something…” << std::endl;
    52.     }
    53.     virtual void handle() override
    54.     {
    55.         doSomethingBSpecial();
    56.     }
    57. };
    58. int _tmain(int argc, _TCHAR* argv[])
    59. {
    60.     A a;
    61.     B* b = new B;
    62.     //这里把 B 的对象注册到消息处理器,使 B 可以处理 doSomethingASpecial 这个消息
    63.     MsgMgr::addReceiver(“doSomethingASpecial”, b);
    64.     a.doSomethingASpecial();
    65.     return 0;
    66. }

      以上的代码都是可以直接复制粘贴在 visual studio 中运行的。

      原创粉丝点击