当前位置: 首页 > news >正文

Chapter14—中介者模式

中介者模式

1 概念

用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。

2 意图(Intent)

用一个中介对象来封装一系列对象交互。中介者使各对象不需要相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

3 动机(Motivate)

在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。在这种情况下,我们可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。

4 类图结构

在这里插入图片描述

5 角色定义

  • Mediator(抽象中介者):抽象中介者用于定义一个接口,该接口用于与各同事对象之间的通信。
  • ConcreteMediator(具体中介者):具体中介者是抽象中介者的子类,通过协调各个同事对象来实现协作行为,了解并维护它对各个同事对象的引用。在通用的中介者模式类图中,具体中介者与各个具体同事类之间有关联关系,在实现时为了保证系统的扩展性,可以根据需要将该引用关联关系建立在抽象层,即具体中介者中定义的是抽象同事角色。
  • Colleague(抽象同事类):抽象同事类定义各同事的公用方法。
  • ConcreteColleague(具体同事类):具体同事类是抽象同事类的子类,每一个同事对象都引用一个中介者对象;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。

6 程序示例

中介者示例

抽象中介者

class Mediator
{
public:Mediator() = default;virtual ~Mediator() = default;public:virtual void DoActionFromAtoB() = 0;virtual void DoActionFromBtoA() = 0;
};

抽象同事类

class Colleage
{
public:Colleage() = default;virtual ~Colleage() = default;Colleage(Mediator* pMediator);public:virtual void Aciton() = 0;void SetState(const string& strState);string GetState();protected:Mediator* m_pMediator;string m_strState;
};Colleage::Colleage(Mediator *pMediator) : m_pMediator(pMediator)
{// ...
}void Colleage::SetState(const string &strState)
{m_strState = strState;
}string Colleage::GetState()
{return m_strState;
}

具体同事类A

class ConcreteColleageA: public Colleage
{
public:ConcreteColleageA() = default;virtual ~ConcreteColleageA() = default;ConcreteColleageA(Mediator* pMediator);public:void Aciton();
};ConcreteColleageA::ConcreteColleageA(Mediator *pMediator) : Colleage(pMediator)
{// ...
}void ConcreteColleageA::Aciton()
{m_pMediator->DoActionFromAtoB();qDebug() << "State of ConcreteColleageA:" << this->GetState().c_str();
}

具体同事类B

class ConcreteColleageB: public Colleage
{
public:ConcreteColleageB() = default;virtual ~ConcreteColleageB() = default;ConcreteColleageB(Mediator* pMediator);public:void Aciton();
};ConcreteColleageB::ConcreteColleageB(Mediator *pMediator) : Colleage(pMediator)
{// ...
}void ConcreteColleageB::Aciton()
{m_pMediator->DoActionFromBtoA();qDebug() << "State of ConcreteColleageB:" << this->GetState().c_str();
}

具体中介者类

class ConcreteMediator: public Mediator
{
public:ConcreteMediator() = default;~ConcreteMediator() = default;ConcreteMediator(Colleage* pColleageA, Colleage* pColleageB);public:void SetConcreteColleageA(Colleage* pColleageA);void SetConcreteColleageB(Colleage* pColleageB);Colleage* GetConcreteColleageA();Colleage* GetConcreteColleageB();void IntroColleage(Colleage* pColleageA, Colleage* pColleageB);void DoActionFromAtoB();void DoActionFromBtoA();private:Colleage* m_pColleageA;Colleage* m_pColleageB;
};ConcreteMediator::ConcreteMediator(Colleage *pColleageA, Colleage *pColleageB):m_pColleageA(), m_pColleageB(pColleageB)
{// ...
}void ConcreteMediator::SetConcreteColleageA(Colleage *pColleageA)
{m_pColleageA = pColleageA;
}void ConcreteMediator::SetConcreteColleageB(Colleage *pColleageB)
{m_pColleageB = pColleageB;
}Colleage *ConcreteMediator::GetConcreteColleageA()
{return m_pColleageA;
}Colleage *ConcreteMediator::GetConcreteColleageB()
{return m_pColleageB;
}void ConcreteMediator::IntroColleage(Colleage *pColleageA, Colleage *pColleageB)
{m_pColleageA = pColleageA;m_pColleageB = pColleageB;
}void ConcreteMediator::DoActionFromAtoB()
{m_pColleageB->SetState(m_pColleageA->GetState());
}void ConcreteMediator::DoActionFromBtoA()
{m_pColleageA->SetState(m_pColleageB->GetState());
}

测试函数类

void ClientTest()
{ConcreteMediator* pConcreteMediator = new ConcreteMediator();ConcreteColleageA* pColleageA = new ConcreteColleageA(pConcreteMediator);ConcreteColleageB* pColleageB = new ConcreteColleageB(pConcreteMediator);pConcreteMediator->IntroColleage(pColleageA, pColleageB);pColleageA->SetState("old");pColleageB->SetState("old");pColleageA->Aciton();pColleageB->Aciton();pColleageA->SetState("new");pColleageA->Aciton();pColleageB->Aciton();pColleageB->SetState("old");pColleageB->Aciton();pColleageA->Aciton();delete pConcreteMediator;delete pColleageA;delete pColleageB;
}

虚拟聊天室示例

示例类图

在这里插入图片描述

抽象中介者类 AbstractChatroom (抽象聊天室类)

class Member;/*** @brief 抽象中介者类 AbstractChatroom (抽象聊天室类)*/
class AbstractChatroom
{
public:AbstractChatroom() = default;virtual ~AbstractChatroom() = default;public:virtual void Rergister(Member* pMember) = 0;virtual void SendText(const string& strFrom, const string& strTo, const string& strMessage) = 0;virtual void SendImage(const string& strFrom, const string& strTo, const string& strImage) = 0;
};

抽象同事类 Member (抽象会员类)

/*** @brief 抽象同事类 Member (抽象会员类)*/
class Member
{
public:Member(const string& strName);virtual ~Member() = default;public:void SetName(const string& strName);string GetName();void SetChatroom(AbstractChatroom* pChatroom);AbstractChatroom* GetChatroom();void ReceiveText(const string& strFrom, const string& strMessage);void ReceiveImage(const string& strFrom, const string& strImage);virtual void SendText(const string& strTo, const string& strMessage) = 0;virtual void SendImage(const string& strTo, const string& strImage) = 0;protected:AbstractChatroom* m_pChatroom;string m_strName;
};Member::Member(const string &strName): m_strName(strName)
{// ...
}void Member::SetName(const string &strName)
{m_strName = strName;
}string Member::GetName()
{return m_strName;
}void Member::SetChatroom(AbstractChatroom *pChatroom)
{m_pChatroom = pChatroom;
}AbstractChatroom *Member::GetChatroom()
{return m_pChatroom;
}void Member::ReceiveText(const string &strFrom, const string &strMessage)
{qDebug() << strFrom.c_str() << "发送文本给" << m_strName.c_str() << ",内容为:" << strMessage.c_str();
}void Member::ReceiveImage(const string &strFrom, const string &strImage)
{qDebug() << strFrom.c_str() << "发送图片给" << m_strName.c_str() << ",内容为:" << strImage.c_str();
}

具体中介者类 ChatGroup (具体聊天室类)

/*** @brief 具体中介者类 ChatGroup (具体聊天室类)*/
class ChatGroup: public AbstractChatroom
{
public:ChatGroup() = default;~ChatGroup() = default;public:void Rergister(Member* pMember) override;void SendText(const string& strFrom, const string& strTo, const string& strMessage) override;void SendImage(const string& strFrom, const string& strTo, const string& strImage) override;private:map<string, Member*> m_MapName2Member;
};void ChatGroup::Rergister(Member *pMember)
{m_MapName2Member[pMember->GetName()] = pMember;pMember->SetChatroom(this);
}void ChatGroup::SendText(const string &strFrom, const string &strTo, const string &strMessage)
{Member* pMember = m_MapName2Member[strTo];pMember->ReceiveText(strFrom, strMessage);
}void ChatGroup::SendImage(const string &strFrom, const string &strTo, const string &strImage)
{Member* pMember = m_MapName2Member[strTo];if (strImage.length() > 10){qDebug() << "图片太大,发送失败!";}else{pMember->ReceiveImage(strFrom, strImage);}
}

具体同事类 CommonMember(普通会员类)

/*** @brief 具体同事类 CommonMember(普通会员类)*/
class CommonMember: public Member
{
public:CommonMember(const string& strName);~CommonMember() = default;public:void SendText(const string& strTo, const string& strMessage) override;void SendImage(const string& strTo, const string& strImage) override;
};CommonMember::CommonMember(const string &strName): Member(strName)
{// ...
}void CommonMember::SendText(const string &strTo, const string &strMessage)
{qDebug() << "普通会员发送信息:";m_pChatroom->SendText(m_strName, strTo, strMessage);    // 发送文本
}void CommonMember::SendImage(const string &strTo, const string &strImage)
{qDebug() << "普通会员不能发送图片!";
}

具体同事类 DiamondMember(钻石会员类)

/*** @brief 具体同事类 DiamondMember(钻石会员类)*/
class DiamondMember: public Member
{
public:DiamondMember(const string& strName);~DiamondMember() = default;public:void SendText(const string& strTo, const string& strMessage) override;void SendImage(const string& strTo, const string& strImage) override;
};DiamondMember::DiamondMember(const string &strName): Member(strName)
{// ...
}void DiamondMember::SendText(const string &strTo, const string &strMessage)
{qDebug() << "钻石会员发送信息:";m_pChatroom->SendText(m_strName, strTo, strMessage);    // 发送文本
}void DiamondMember::SendImage(const string &strTo, const string &strImage)
{qDebug() << "钻石会员发送图片:";m_pChatroom->SendImage(m_strName, strTo, strImage);    // 发送图片
}

测试函数

/*** @brief 测试函数*/
void ClientTest()
{AbstractChatroom* pChatroom = new ChatGroup();Member* pMember1 = new DiamondMember("张三");Member* pMember2 = new DiamondMember("李四");Member* pMember3 = new DiamondMember("王五");Member* pMember4 = new CommonMember("小芳");Member* pMember5 = new CommonMember("小红");pChatroom->Rergister(pMember1);pChatroom->Rergister(pMember2);pChatroom->Rergister(pMember3);pChatroom->Rergister(pMember4);pChatroom->Rergister(pMember5);pMember1->SendText("李四", "李四,你好!");pMember2->SendText("张三", "张三,你好!");pMember1->SendText("李四", "今天天气不错,有太阳!");pMember2->SendImage("张三", "一个很大很大的太阳!");pMember2->SendImage("张三", "太阳");pMember3->SendText("小芳", "还有问题吗?");pMember3->SendText("小红", "还有问题吗?");pMember4->SendText("王五", "没有了,谢谢!");pMember5->SendText("小红", "我也没有了!");pMember5->SendImage("王五", "谢谢!");delete pChatroom;delete pMember1;delete pMember2;delete pMember3;delete pMember4;delete pMember5;
}

7 思考小结

中介者模式优点:

  • 简化了对象之间的交互
  • 将各同事解耦
  • 减少子类生成

中介者模式的适用场景:

  • 系统中对象之间存在复杂的引用和通信关系,产生的互相依赖关系结构混乱且难以理解。
  • 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
  • 想定制一个分布在多个类中的行为,而又不想生成太多的子类。
http://www.dtcms.com/a/548636.html

相关文章:

  • Python 教程:将 PPT(X) 转换为 PDF
  • [MySQL]字符串函数
  • h5游戏免费下载:暴打小苹果
  • Java 网络编程:TCP 与 UDP 的「通信江湖」(基于TCP回显服务器)
  • VMD-Transformer-LSTM组合模型锂电池剩余寿命预测(NASA电池数据集容量特征提取+RUL电池剩余寿命预测)MATLAB代码
  • 告别手搓PPT:实测四款免费AI生成工具
  • 如何在 iPhone 上录制屏幕 - 三大方法
  • 界面简洁,上手快!适合新手的免费PPT生成软件推荐
  • cdr做网站新乐做网站优化
  • 长沙网站建设联系电话asp网站免费模板下载
  • Gorm散知识点小结--标签名
  • python语言基础-6 多任务-6.0 基本概念
  • 四川省工程建设信息官方网站郴州做网站ku0735
  • Kubernetes 资源管理总结
  • 【源码+数据集+训练教程】基于YOLOv8+Flask+Layui的智能垃圾分类检测系统
  • X_T 转换为 3DXML 的技术指南及迪威模型网在线转换推荐
  • NumPy 2.x 完全指南【四十二】线性代数之向量运算
  • 制作网站要求com网站注册域名
  • 网站建设教程搭建芽嘱湖南岚鸿信赖营销单页网站模板
  • 【RDMA】mlx5dev mlx5dv_devx 接口
  • 【墨铺网教程】一台电脑加入多个局域网,让电脑做上传下载主力又当存储盘
  • 变身智能车载台,AORO P9000U三防平板赋能工业数字化升级
  • 安全登录多人共用的机密电脑:基于动态凭证与会话隔离的解决方案
  • 全球首款卷轴屏电脑发布!ToDesk+扩展屏成平替方案
  • 在Lua用luasql-sqlite3库访问SQLite数据库
  • 代码随想录第51 52天 | 图论-岛屿问题汇总
  • 分布式存储:Ceph、GlusterFS、MinIO架构与部署
  • 机械外协加工网最新订单移动网站如何优化排名
  • 11 种方法解决小米/米手机无法通过 USB 连接电脑的问题
  • Ubuntu:设置程序开机自启动