设计模式---中介者模式

打印 上一主题 下一主题

主题 630|帖子 630|积分 1890

定义与设计思路



  • 定义:用一个中介对象来封装一系列对象交互。中介者使各对象不需要相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,属于行为型模式。
  • 设计思路:用一个中介对象来封装一系列的对象交互操纵,中介者模式使得对象之间不需要显示的相互引用,从而使得系统或模块内部相互解耦,而且可以独立的改变它们至今的交互
中介者模式的引入:机场控制塔

想象一个繁忙的机场,有很多飞机在同一时间内腾飞和降落。如果每架飞机都直接与其他飞机通信,协商谁该先腾飞、谁该先降落,整个机场的调理将变得非常复杂。每架飞机都要知道其他全部飞机的状态、飞行路线、优先级等,导致信息的传递和处理变得杂乱而低效。
题目:飞机之间的复杂通信
直接通信导致杂乱: 每架飞机要知道并与其他全部飞机通信,管理腾飞、降落的顺序会变得非常困难且伤害。


  • 维护本钱高: 增加或移除一架飞机,全部飞机的通信方式都需要更新,增加了维护的难度。
  • 耦合度过高: 每架飞机相互依赖,任何一个飞机的变更可能会影响整个系统的稳定性。
中介模式解决题目:引入机场控制塔
为了简化调理过程,机场引入了控制塔作为中介者。控制塔的职责是协调全部飞机的腾飞和降落,包管每架飞机都能安全有- 序地运行。这样,每架飞机只需要与控制塔通信,而不需要关心其他飞机的具体状态。


  • 控制塔(中介者): 控制飞机的腾飞和降落顺序,管理它们的路线和时间安排。
  • 飞机(同事类): 负责向控制塔报告自己的状态(如预备腾飞、预备降落等),并接收控制塔的指令(如可以腾飞或等候)。
中介模式的作用:
去耦合: 飞机之间不再直接通信,只需要和控制塔交互,这大大简化了飞机之间的相互依赖。
集中控制: 全部的调理逻辑都集中在控制塔中,便于同一管理,维护起来更加简朴。
易于扩展: 新的飞机可以轻松参加机场系统,只需要和控制塔通信,而不需要重新调整其他飞机的通信逻辑。
中介者模式的设计框架

需要一个中介者类和同事类,目标是通过中介者类对象对象完成同事类实例之间的信息交互。此中,中介者类中需要有一个储存注册进来的同事对象的列表、发送消息的接口(协助同事实例完成消息的转发)、注册函数(完成同事实例的注册)。全部的同事类实例包含一个发布消息接口、接收消息的接口(接收中介转发的消息),别的包含一个中介实例成员变量(用于完成消息的转发的接口对象)。
中介模式的关键要素:


  • 中介者(Mediator): 中介者负责定义对象之间的通信接口,具体的通信逻辑则由具体的中介者实现。
  • 具体中介者(Concrete Mediator): 这是中介者的具体实现,它维护全部加入者对象,并处理这些对象之间的通信。
  • 同事类(Colleague): 这些是加入通信的对象,它们通过中介者进行相互通信,而不是直接引用其他同事对象。
  1. #include <bits/stdc++.h>
  2. //
  3. //中介者模式
  4. //关键代码:对象 Colleague 之间的通信封装到一个类中单独处理
  5. //
  6. class Mediator;
  7. //抽象人(同事类)
  8. class Person
  9. {
  10. protected:
  11.     std::shared_ptr<Mediator> m_mediator; //中介类实例
  12. public:
  13.     Person(const std::shared_ptr<Mediator> pMediator) : m_mediator(pMediator) {}
  14.         //虚析构函数
  15.     virtual ~Person() = default;
  16.     //向中介发送信息
  17.     virtual void SendMessage(const std::string &message) = 0;
  18.     //从中介获取信息
  19.     //message 中介向该对象发送的信息/从中介获取的信息
  20.     virtual void GetMessage(const std::string &message) = 0;
  21. };
  22. //抽象中介机构
  23. class Mediator
  24. {
  25. public:
  26.     virtual ~Mediator() = default;
  27.     //由于后面this指针的原因,此处未采用智能指针
  28.     virtual void Send(std::string message, const Person *from_person) const = 0;
  29.     virtual void Register(std::shared_ptr<Person> pPerson) = 0;
  30. };
  31. //租房者A
  32. class RenterA : public Person
  33. {
  34. public:
  35.     RenterA(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}
  36.     void SendMessage(const std::string &message) override
  37.     {
  38.       m_mediator->Send(message, this);
  39.     }
  40.     void GetMessage(const std::string &message) override
  41.     {
  42.       std::cout << "租房者A收到信息" << message << std::endl;;
  43.     }
  44. };
  45. //租房者B
  46. class RenterB : public Person
  47. {
  48. public:
  49.     RenterB(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}
  50.     void SendMessage(const std::string &message) override
  51.     {
  52.       m_mediator->Send(message, this);
  53.     }
  54.     void GetMessage(const std::string &message) override
  55.     {
  56.       std::cout << "租房者B收到信息" << message << std::endl;;
  57.     }
  58. };
  59. //房东
  60. class Landlord : public Person
  61. {
  62. public:
  63.     Landlord(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}
  64.     void SendMessage(const std::string &message) override
  65.     {
  66.       m_mediator->Send(message, this);
  67.     }
  68.     void GetMessage(const std::string &message) override
  69.     {
  70.       std::cout << "房东收到信息:" << message << std::endl;;
  71.     }
  72. };
  73. //房屋中介
  74. class HouseMediator : public Mediator
  75. {
  76. private:
  77.     //也可以采用多个list,将多个房东放入一个list,将多个求租者放入一个list
  78.     std::vector<std::shared_ptr<Person>> m_pPersonList;
  79. public:
  80.     void Register(const std::shared_ptr<Person> pPerson) override
  81.     {
  82.       //没有添加该同事,则添加进去
  83.       auto iter = m_pPersonList.begin();
  84.       for (; iter != m_pPersonList.end(); ++iter)
  85.       {
  86.         if (*iter == pPerson)
  87.           break;
  88.       }
  89.       if (iter == m_pPersonList.end())
  90.         m_pPersonList.emplace_back(pPerson);
  91.     }
  92.     void Send(std::string message, const Person *from_person) const override
  93.     {
  94.       //接收消息的对象为该对象的对应对象
  95.       for (const auto item:m_pPersonList)
  96.       {
  97.         //此处采用typeid,而非直接判断指针是否相等为同一个对象.
  98.         if (typeid(*item.get()) != typeid(*from_person))
  99.         {
  100.           item->GetMessage(message);
  101.         }
  102.       }
  103.     }
  104. };
  105. int main() {
  106.   std::shared_ptr<Mediator> pHouseMediator = std::make_shared<HouseMediator>();
  107.   std::shared_ptr<Person> pRenterA = std::make_shared<RenterA>(pHouseMediator);
  108.   std::shared_ptr<Person> pRenterB = std::make_shared<RenterB>(pHouseMediator);
  109.   std::shared_ptr<Person> pLandlord = std::make_shared<Landlord>(pHouseMediator);
  110.   pHouseMediator->Register(pRenterA);
  111.   pHouseMediator->Register(pRenterB);
  112.   pHouseMediator->Register(pLandlord);
  113.   pLandlord->SendMessage("出租房子:中山路100号,50平米,2000元一个月");//所有的求租者将会收到该消息
  114.   std::cout << std::string(50, '-') << std::endl;
  115.   pRenterA->SendMessage("我想在中山路附近租套房子,价格1500元一个月");//所有的房东将会收到该消息
  116.   return 0;
  117. }
复制代码
输出
  1. 租房者A收到信息出租房子:中山路100号,50平米,2000元一个月
  2. 租房者B收到信息出租房子:中山路100号,50平米,2000元一个月
  3. --------------------------------------------------
  4. 租房者B收到信息我想在中山路附近租套房子,价格1500元一个月
  5. 房东收到信息:我想在中山路附近租套房子,价格1500元一个月
复制代码
发送的消息通过中介转发给租房者,租房者发送的消息通过中介转发给
感谢大佬的解说
   https://blog.csdn.net/leonardohaig/article/details/109963550

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表