定义与设计思路
- 定义:用一个中介对象来封装一系列对象交互。中介者使各对象不需要相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,属于行为型模式。
- 设计思路:用一个中介对象来封装一系列的对象交互操纵,中介者模式使得对象之间不需要显示的相互引用,从而使得系统或模块内部相互解耦,而且可以独立的改变它们至今的交互
中介者模式的引入:机场控制塔
想象一个繁忙的机场,有很多飞机在同一时间内腾飞和降落。如果每架飞机都直接与其他飞机通信,协商谁该先腾飞、谁该先降落,整个机场的调理将变得非常复杂。每架飞机都要知道其他全部飞机的状态、飞行路线、优先级等,导致信息的传递和处理变得杂乱而低效。
题目:飞机之间的复杂通信
直接通信导致杂乱: 每架飞机要知道并与其他全部飞机通信,管理腾飞、降落的顺序会变得非常困难且伤害。
- 维护本钱高: 增加或移除一架飞机,全部飞机的通信方式都需要更新,增加了维护的难度。
- 耦合度过高: 每架飞机相互依赖,任何一个飞机的变更可能会影响整个系统的稳定性。
中介模式解决题目:引入机场控制塔
为了简化调理过程,机场引入了控制塔作为中介者。控制塔的职责是协调全部飞机的腾飞和降落,包管每架飞机都能安全有- 序地运行。这样,每架飞机只需要与控制塔通信,而不需要关心其他飞机的具体状态。
- 控制塔(中介者): 控制飞机的腾飞和降落顺序,管理它们的路线和时间安排。
- 飞机(同事类): 负责向控制塔报告自己的状态(如预备腾飞、预备降落等),并接收控制塔的指令(如可以腾飞或等候)。
中介模式的作用:
去耦合: 飞机之间不再直接通信,只需要和控制塔交互,这大大简化了飞机之间的相互依赖。
集中控制: 全部的调理逻辑都集中在控制塔中,便于同一管理,维护起来更加简朴。
易于扩展: 新的飞机可以轻松参加机场系统,只需要和控制塔通信,而不需要重新调整其他飞机的通信逻辑。
中介者模式的设计框架
需要一个中介者类和同事类,目标是通过中介者类对象对象完成同事类实例之间的信息交互。此中,中介者类中需要有一个储存注册进来的同事对象的列表、发送消息的接口(协助同事实例完成消息的转发)、注册函数(完成同事实例的注册)。全部的同事类实例包含一个发布消息接口、接收消息的接口(接收中介转发的消息),别的包含一个中介实例成员变量(用于完成消息的转发的接口对象)。
中介模式的关键要素:
- 中介者(Mediator): 中介者负责定义对象之间的通信接口,具体的通信逻辑则由具体的中介者实现。
- 具体中介者(Concrete Mediator): 这是中介者的具体实现,它维护全部加入者对象,并处理这些对象之间的通信。
- 同事类(Colleague): 这些是加入通信的对象,它们通过中介者进行相互通信,而不是直接引用其他同事对象。
- #include <bits/stdc++.h>
- //
- //中介者模式
- //关键代码:对象 Colleague 之间的通信封装到一个类中单独处理
- //
- class Mediator;
- //抽象人(同事类)
- class Person
- {
- protected:
- std::shared_ptr<Mediator> m_mediator; //中介类实例
- public:
- Person(const std::shared_ptr<Mediator> pMediator) : m_mediator(pMediator) {}
- //虚析构函数
- virtual ~Person() = default;
- //向中介发送信息
- virtual void SendMessage(const std::string &message) = 0;
- //从中介获取信息
- //message 中介向该对象发送的信息/从中介获取的信息
- virtual void GetMessage(const std::string &message) = 0;
- };
- //抽象中介机构
- class Mediator
- {
- public:
- virtual ~Mediator() = default;
- //由于后面this指针的原因,此处未采用智能指针
- virtual void Send(std::string message, const Person *from_person) const = 0;
- virtual void Register(std::shared_ptr<Person> pPerson) = 0;
- };
- //租房者A
- class RenterA : public Person
- {
- public:
- RenterA(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}
- void SendMessage(const std::string &message) override
- {
- m_mediator->Send(message, this);
- }
- void GetMessage(const std::string &message) override
- {
- std::cout << "租房者A收到信息" << message << std::endl;;
- }
- };
- //租房者B
- class RenterB : public Person
- {
- public:
- RenterB(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}
- void SendMessage(const std::string &message) override
- {
- m_mediator->Send(message, this);
- }
- void GetMessage(const std::string &message) override
- {
- std::cout << "租房者B收到信息" << message << std::endl;;
- }
- };
- //房东
- class Landlord : public Person
- {
- public:
- Landlord(const std::shared_ptr<Mediator> mediator) : Person(mediator) {}
- void SendMessage(const std::string &message) override
- {
- m_mediator->Send(message, this);
- }
- void GetMessage(const std::string &message) override
- {
- std::cout << "房东收到信息:" << message << std::endl;;
- }
- };
- //房屋中介
- class HouseMediator : public Mediator
- {
- private:
- //也可以采用多个list,将多个房东放入一个list,将多个求租者放入一个list
- std::vector<std::shared_ptr<Person>> m_pPersonList;
- public:
- void Register(const std::shared_ptr<Person> pPerson) override
- {
- //没有添加该同事,则添加进去
- auto iter = m_pPersonList.begin();
- for (; iter != m_pPersonList.end(); ++iter)
- {
- if (*iter == pPerson)
- break;
- }
- if (iter == m_pPersonList.end())
- m_pPersonList.emplace_back(pPerson);
- }
- void Send(std::string message, const Person *from_person) const override
- {
- //接收消息的对象为该对象的对应对象
- for (const auto item:m_pPersonList)
- {
- //此处采用typeid,而非直接判断指针是否相等为同一个对象.
- if (typeid(*item.get()) != typeid(*from_person))
- {
- item->GetMessage(message);
- }
- }
- }
- };
- int main() {
- std::shared_ptr<Mediator> pHouseMediator = std::make_shared<HouseMediator>();
- std::shared_ptr<Person> pRenterA = std::make_shared<RenterA>(pHouseMediator);
- std::shared_ptr<Person> pRenterB = std::make_shared<RenterB>(pHouseMediator);
- std::shared_ptr<Person> pLandlord = std::make_shared<Landlord>(pHouseMediator);
- pHouseMediator->Register(pRenterA);
- pHouseMediator->Register(pRenterB);
- pHouseMediator->Register(pLandlord);
- pLandlord->SendMessage("出租房子:中山路100号,50平米,2000元一个月");//所有的求租者将会收到该消息
- std::cout << std::string(50, '-') << std::endl;
- pRenterA->SendMessage("我想在中山路附近租套房子,价格1500元一个月");//所有的房东将会收到该消息
- return 0;
- }
复制代码 输出
- 租房者A收到信息出租房子:中山路100号,50平米,2000元一个月
- 租房者B收到信息出租房子:中山路100号,50平米,2000元一个月
- --------------------------------------------------
- 租房者B收到信息我想在中山路附近租套房子,价格1500元一个月
- 房东收到信息:我想在中山路附近租套房子,价格1500元一个月
复制代码 发送的消息通过中介转发给租房者,租房者发送的消息通过中介转发给
感谢大佬的解说
https://blog.csdn.net/leonardohaig/article/details/109963550
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |