• C++行为型模式-中介者模式


    1 模式介绍

    中介者模式(Mediator Pattern):用一个中介对象来封装一系列的对象交互,中介者使得各对象不需要显示地相互引用,从而使得耦合松散,而且可以独立地改变它们之间的交互。

    面向对象设计鼓励将行为分布到各个对象中。但是,这种分布可能会导致对象间有许多连接。每一个对象都知道其他所有对象,就造成了复杂的关系。对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。

    中介者模式是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。  

    2 模式结构

     (1)抽象中介者(Mediator)

    抽象中介者用于定义一个接口,接口用于各同事之间的通信。

    (2)具体中介者(ConcreteMediator)

    具体中介者是抽象中介者的子类,通过协调各个同事对象来实现协作行为,了解并维护它对各个同事对象的引用。

    (3)抽象同事类(Colleague)

    抽象同事类定义各同事的公有方法。

    (4)具体同事类(ConcreteColleague)

    具体同事类是抽象同事类的子类,每一个同事对象都引用一个中介者对象;

    每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;

    3 模式优缺点

    3.1 优点

    (1)简化了对象之间的交互。用中介者和同事的一对多的关系代替了原来同事之间的多对交互。

    (2)将各同事解耦。中介者有利于各同事之间的松耦合。

    (3)减少子类生成。

    3.2 缺点

    在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,使能系统难以维护。

    4 模式应用

    (1)系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱难以理解。

    (2)一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。

    应用实例: 1、中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。 2、机场调度系统。 3、MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

    5 模式实现

    利用中介者模式实现聊天是功能。

    1. #include
    2. using namespace std;
    3. #define SAFE_DELETE(p) if (p) { delete p; p = NULL; }
    4. //抽象中介者
    5. class Mediator;
    6. //抽象同事类
    7. class Colleague
    8. {
    9. public:
    10. Colleague(Mediator *pMediator) : m_pMediator(pMediator){}
    11. virtual void Send(char *message) = 0;
    12. protected:
    13. Mediator *m_pMediator;
    14. };
    15. //具体同事类1
    16. class ConcreteColleague1 : public Colleague
    17. {
    18. public:
    19. ConcreteColleague1(Mediator *pMediator) : Colleague(pMediator){}
    20. void Send(char *message);
    21. void Notify(char *message)
    22. {
    23. wcout<
    24. }
    25. };
    26. //具体同事类2
    27. class ConcreteColleague2 : public Colleague
    28. {
    29. public:
    30. ConcreteColleague2(Mediator *pMediator) : Colleague(pMediator){}
    31. void Send(char *message);
    32. void Notify(char *message)
    33. {
    34. cout<<"ConcreteColleague2 is handling the message."<
    35. wcout<
    36. }
    37. };
    38. //抽象中介者类
    39. class Mediator
    40. {
    41. public:
    42. virtual void Sent(char *message, Colleague *pColleague) = 0;
    43. };
    44. //具体中介者类
    45. class ConcreteMediator : public Mediator
    46. {
    47. public:
    48. // The mediator forward the message
    49. void Sent(char *message, Colleague *pColleague)
    50. {
    51. ConcreteColleague1 *pConcreteColleague1 = dynamic_cast(pColleague);
    52. if (pConcreteColleague1)
    53. {
    54. cout<<"The message is from ConcreteColleague1. Now mediator forward it to ConcreteColleague2"<
    55. if (m_pColleague2)
    56. {
    57. m_pColleague2->Notify(message);
    58. }
    59. }
    60. else
    61. {
    62. if (m_pColleague1)
    63. {
    64. m_pColleague1->Notify(message);
    65. }
    66. }
    67. }
    68. void SetColleague1(Colleague *pColleague)
    69. {
    70. m_pColleague1 = dynamic_cast(pColleague);
    71. }
    72. void SetColleague2(Colleague *pColleague)
    73. {
    74. m_pColleague2 = dynamic_cast(pColleague);
    75. }
    76. private:
    77. // The Mediator knows all the Colleague
    78. ConcreteColleague1 *m_pColleague1;
    79. ConcreteColleague2 *m_pColleague2;
    80. };
    81. void ConcreteColleague1::Send(char *message)
    82. {
    83. // The second parameter mark where the message comes from
    84. m_pMediator->Sent(message, this);
    85. }
    86. void ConcreteColleague2::Send(char *message)
    87. {
    88. m_pMediator->Sent(message, this);
    89. }
    90. int main()
    91. {
    92. // Create the mediator
    93. Mediator *pMediator = new ConcreteMediator();
    94. Colleague *pColleague1 = new ConcreteColleague1(pMediator);
    95. Colleague *pColleague2 = new ConcreteColleague2(pMediator);
    96. ConcreteMediator *pConcreteMediator = dynamic_cast(pMediator);
    97. pConcreteMediator->SetColleague1(pColleague1);
    98. pConcreteMediator->SetColleague2(pColleague2);
    99. char message[260] = "Where are you from?";
    100. pColleague1->Send(message);
    101. return 0;
    102. }

    输出信息: 

    The message is from ConcreteColleague1. Now mediator forward it to ConcreteColleague2
    ConcreteColleague2 is handling the message.
    Where are you from?
     

    6 中介者与外观者模式的区别

    外观模式与中介者模式的不同之处在于,外观模式是对一个对象子系统进行抽象,从而提供了一个更为方便的接口;外观模式的协议是单向的,即外观模式向子系统提出请求,但反过来则不行;而对于中介者模式,是进行多个对象之间的协作,通信是多向的。 

    参考文献:

    【1】C++设计模式——中介者模式 - Ring_1992 - 博客园

    【2】中介者模式 | 菜鸟教程 

  • 相关阅读:
    AcWing-C/C++语法基础【合集2】
    数字IC笔试题和回答整理
    虚拟网络编辑器三种模式工作原理详细介绍(桥接-网络地址转换-主机模式)
    x64 简介
    Keepalived+LVS高可用集群
    [附源码]JAVA毕业设计个人饮食营养管理信息系统(系统+LW)
    【面试:并发篇38:多线程:线程池】ThreadPoolExecutor类的基本概念
    数据分析-Pandas数据探查初步:离散点图
    C# excel操作
    永久关闭win10系统自动更新以及如何部署虚拟机以win xp为例
  • 原文地址:https://blog.csdn.net/kenjianqi1647/article/details/122951386