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

Chapter14—中介者模式 - 教程

中介者模式

1 概念

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

2 意图(Intent)

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

3 动机(Motivate)

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

4 类图结构

在这里插入图片描述

5 角色定义

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.jsqmd.com/news/363043/

相关文章:

  • 统领工业 “智能大脑”,以根技术开启自主控制新纪元
  • ANELLO Photonics 与 Delta Black Aerospace 展开合作
  • GP8501 PWM转0-2.5V模拟电压模块原理图设计,已量产
  • 职业教育的“风口”已变!职业教育相关从业者,这波红利你赶上了吗?
  • Java毕设项目推荐-基于 SpringBoot 的高校办公室行政事务管理系统设计与实现基于springboot的校园行政事务审批服务系统的设计与开发【附源码+文档,调试定制服务】
  • VMD-SE-LSTM+Transformer多变量时序预测,MATLAB代码
  • GP8503 I2C转0-2.5V模拟电压模块原理图设计,已量产
  • Java毕设项目:基于springboot的校园行政事务审批服务系统的设计与开发(源码+文档,讲解、调试运行,定制等)
  • 手把手教你在Win10上为Vibe Writing项目搭建Claude Code环境
  • 软件工程专业毕业设计选题方向汇总(2026最新版|含难度分级+技术栈)
  • #车载测试:基于Python与CAPL的程控电源协同控制方案
  • 2026年市场调查优质机构推荐榜:第三方市场调查机构推荐/第三方市场调查机构推荐/第三方市场调研公司推荐/选择指南 - 优质品牌商家
  • jQuery 添加元素
  • SAP S4HANA 2025 FAA虚拟机介绍
  • c++-—
  • 免费网站模板下载网站
  • ue5 正确关闭自动曝光
  • 职教数字化八年观察:当代码成为产教融合的“隐形桥梁”
  • Solution - P5471 [NOI2019] 弹跳
  • Excel条件格式高级应用:动态图标集标记成绩与平均分比较
  • 防冻液优质厂家推荐及选购指南 - 优质品牌商家
  • [python]-LangChain
  • Java毕设项目推荐-基于Spring Boot的社区便民服务管理系统的设计与实现基于springboot的在线社区系统的设计与开发【附源码+文档,调试定制服务】
  • 数字模型赋能大规模设计,连通城市与河流
  • 铁木辛柯梁振动分析仿真 COMSOL案例还原及 此模型研究深梁的自由振动和强迫振动
  • [Informatics] (Legacy) CodeForces + Atcoder 问题几则
  • 成都美术艺考集训机构优质推荐榜:美术艺考校考培训机构/美术艺考集训培训机构/美术艺考集训学校/专业美术艺考培训/选择指南 - 优质品牌商家
  • Java毕设选题推荐:基于springboot的在线社区系统的设计与开发基于Spring Boot的社区便民服务管理系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 技术项目招人难、用人贵?唐普 IT 人力外包,帮企业破解人力卡点难题
  • BeeWorks企业通讯:赋能企业高效沟通,守护安全协同新生态