中介者模式概念:
在软件设计中,中介者模式(Mediator Pattern)是一种行为设计模式,它可以用来减少对象之间的直接依赖性,通过引入一个中介者对象来协调各个对象的交互。这样做的好处是,可以将对象间复杂的网状关系简化为星状关系,有助于提高系统的可维护性和扩展性。
没有中间者(主板)
有中介者(主板):
一个游戏登录框:
namespace _nmsp1 { //UI控件类的父类 class CtlParent { public: CtlParent(string caption) :m_caption(caption) {} //构造函数 virtual ~CtlParent() {} //做父类时析构函数应该为虚函数 public: //当UI控件发生变化时该成员函数会被调用 virtual void Changed(map<string, CtlParent*>& tmpuictllist) = 0; //形参所代表的map容器中包含着所有对话框中涉及的UI控件。 //设置UI控件启用或者禁用 virtual void Enable(bool sign) = 0; protected: string m_caption; //控件上面显示的文字内容,本范例假设每个UI空间上的文字都不同 }; //普通按钮相关类 class Button :public CtlParent { public: Button(string caption) :CtlParent(caption) {} //构造函数 //设置按钮的启用或者禁用 virtual void Enable(bool sign) { if (sign == true) { cout << "按钮\"" << m_caption << "\"被设置为了\"启用\"状态" << endl; } else { cout << "按钮\"" << m_caption << "\"被设置为了\"禁用\"状态" << endl; } //......具体实现按钮启用或者禁用的代码。。。。 } //按钮被按下时该成员函数会被调用 virtual void Changed(map<string, CtlParent*>& tmpuictllist); }; //单选按钮相关类 class RadioBtn :public CtlParent { public: RadioBtn(string caption) :CtlParent(caption) {} //构造函数 //设置单选按钮的启用或者禁用 virtual void Enable(bool sign) { //本范例用不到该功能,实现代码略...... } //设置单选按钮被选中或者被取消选中,被选中的单选按钮中间有个黑色的实心圆点 void Selected(bool sign) { if (sign == true) { cout << "单选按钮\"" << m_caption << "\"被选中" << endl; } else { cout << "单选按钮\"" << m_caption << "\"被取消选中" << endl; } //......具体实现单选按钮启用或者取消选中的代码略。。。。。 } //单选按钮被单击时该成员函数会被调用 virtual void Changed(map<string, CtlParent*>& tmpuictllist); }; //编辑框相关类 class EditCtl :public CtlParent { public: EditCtl(string caption) :CtlParent(caption) {} //构造函数 //设置编辑框的启用或者禁用 virtual void Enable(bool sign) { if (sign == true) { cout << "编辑框\"" << m_caption << "\"被设置为了\"启用\"状态" << endl; } else { cout << "编辑框\"" << m_caption << "\"被设置为了\"禁用\"状态" << endl; } //......具体实现编辑框启用或者禁用的代码。。。。 } //是否编辑框中的内容为空 bool isContentEmpty() { return m_content.empty(); } //编辑框内容发生变化时该成员函数会被调用 virtual void Changed(map<string, CtlParent*>& tmpuictllist); private: string m_content = ""; //编辑框中的内容 }; //--------------------------- //普通按钮被按下是该成员函数会被调用 void Button::Changed(map<string, CtlParent*>& tmpuictllist) { if (m_caption == "登录") { //按下的是登录按钮 cout << "开始游戏登录验证,根据验证结果决定是否进入游戏之中还是验证失败给出提示!" << endl; } else if (m_caption == "退出") { //按下的是退出按钮,则退出整个游戏 cout << "游戏退出,再见!" << endl; } } //单选按钮被单击时该成员函数会被调用 void RadioBtn::Changed(map<string, CtlParent*>& tmpuictllist) { if (m_caption == "游客登录") { (static_cast<RadioBtn*>(tmpuictllist["游客登录"]))->Selected(true); //游客登录 单选按钮被选中 (static_cast<RadioBtn*>(tmpuictllist["账号登录"]))->Selected(false); //账号登录 单选按钮被取消选中 tmpuictllist["账号"]->Enable(false); //账号 编辑框设置为禁用 tmpuictllist["密码"]->Enable(false); //密码 编辑框设置为禁用 tmpuictllist["登录"]->Enable(true); //登录 按钮设置为启用 } else if (m_caption == "账号登录") { (static_cast<RadioBtn*>(tmpuictllist["账号登录"]))->Selected(true); //账号登录 单选按钮被选中 (static_cast<RadioBtn*>(tmpuictllist["游客登录"]))->Selected(false); //游客登录 单选按钮被取消选中 tmpuictllist["账号"]->Enable(true); //账号 编辑框设置为启用 tmpuictllist["密码"]->Enable(true); //密码 编辑框设置为启用 if ((static_cast<EditCtl*>(tmpuictllist["账号"]))->isContentEmpty() || (static_cast<EditCtl*>(tmpuictllist["密码"]))->isContentEmpty()) { //如果 账号 编辑框 或者 密码 编辑框 有一个为空,则不允许登录 tmpuictllist["登录"]->Enable(false); //登录 按钮设置为禁用 } else { tmpuictllist["登录"]->Enable(true); //登录 按钮设置为启用 } } } //编辑框内容发生变化时该成员函数会被调用 void EditCtl::Changed(map<string, CtlParent*>& tmpuictllist) { if ((static_cast<EditCtl*>(tmpuictllist["账号"]))->isContentEmpty() || (static_cast<EditCtl*>(tmpuictllist["密码"]))->isContentEmpty()) { //如果 账号 编辑框 或者 密码 编辑框 有一个为空,则不允许登录 tmpuictllist["登录"]->Enable(false); //登录 按钮设置为禁用 } else { tmpuictllist["登录"]->Enable(true); //登录 按钮设置为启用 } } } int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口 //创建各种UI控件 map<string, _nmsp1::CtlParent*> uictllist; //将所有创建的UI控件保存到map容器中,方便进行参数传递 uictllist["登录"] = new _nmsp1::Button("登录"); uictllist["退出"] = new _nmsp1::Button("退出"); uictllist["游客登录"] = new _nmsp1::RadioBtn("游客登录"); uictllist["账号登录"] = new _nmsp1::RadioBtn("账号登录"); uictllist["账号"] = new _nmsp1::EditCtl("账号"); uictllist["密码"] = new _nmsp1::EditCtl("密码"); //设置一下缺省的UI控件状态 (static_cast<_nmsp1::RadioBtn*>(uictllist["游客登录"]))->Selected(true); //游客登录 单选按钮被选中 (static_cast<_nmsp1::RadioBtn*>(uictllist["账号登录"]))->Selected(false); //账号登录 单选按钮被取消选中 uictllist["账号"]->Enable(false); //账号 编辑框设置为禁用 uictllist["密码"]->Enable(false); //密码 编辑框设置为禁用 uictllist["登录"]->Enable(true); //登录 按钮设置为启用 uictllist["退出"]->Enable(true); //退出 按钮设置为启用 cout << "------------------------" << endl; uictllist["账号登录"]->Changed(uictllist); //模拟 账号登录 单选按钮被单击选中 //释放资源 for (auto iter = uictllist.begin(); iter != uictllist.end(); ++iter) { delete iter->second; iter->second = nullptr; } return 0; }
中介者(Mediator)模式:调停者模式,行为型模式。
//a)计算的各个组成部件:主板
//b)qq聊天:与好友或者陌生人单独聊天(私聊);加入到一个qq群中。
//c)飞机的安全飞行与安全着陆:塔台
//(2)中介者模式范例的引入:事件类驱动的软件中有比较广泛的应用,尤其是常常运用在程序的UI界面设计中
#include <iostream> #include <string> #include <vector> #include <memory> // 前向声明 class Colleague; class ConcreteColleagueA; class ConcreteColleagueB; // 抽象中介者类 class Mediator { public: virtual void sendMessage(const std::string &message, Colleague *colleague) = 0; }; // 抽象同事类 class Colleague { protected: Mediator *mediator; public: Colleague(Mediator *mediator) : mediator(mediator) {} virtual void receiveMessage(const std::string &message) = 0; }; // 具体同事类A class ConcreteColleagueA : public Colleague { public: ConcreteColleagueA(Mediator *mediator) : Colleague(mediator) {} void sendMessage(const std::string &message) { mediator->sendMessage(message, this); } void receiveMessage(const std::string &message) override { std::cout << "Colleague A received: " << message << std::endl; } }; // 具体同事类B class ConcreteColleagueB : public Colleague { public: ConcreteColleagueB(Mediator *mediator) : Colleague(mediator) {} void sendMessage(const std::string &message) { mediator->sendMessage(message, this); } void receiveMessage(const std::string &message) override { std::cout << "Colleague B received: " << message << std::endl; } }; // 具体中介者类 class ConcreteMediator : public Mediator { private: std::unique_ptr<ConcreteColleagueA> colleagueA; std::unique_ptr<ConcreteColleagueB> colleagueB; public: void setColleagueA(ConcreteColleagueA *colleague) { colleagueA.reset(colleague); } void setColleagueB(ConcreteColleagueB *colleague) { colleagueB.reset(colleague); } void sendMessage(const std::string &message, Colleague *colleague) override { if (colleague == colleagueA.get()) { colleagueB->receiveMessage(message); } else if (colleague == colleagueB.get()) { colleagueA->receiveMessage(message); } } }; int main() { ConcreteMediator mediator; ConcreteColleagueA colleagueA(&mediator); ConcreteColleagueB colleagueB(&mediator); mediator.setColleagueA(&colleagueA); mediator.setColleagueB(&colleagueB); colleagueA.sendMessage("Hello from A"); colleagueB.sendMessage("Hello from B"); return 0; }
-
抽象中介者类 (
Mediator
):- 定义了一个接口
sendMessage
,用于传递消息。
- 定义了一个接口
-
抽象同事类 (
Colleague
):- 持有一个指向
Mediator
的指针。 - 定义了一个纯虚函数
receiveMessage
用于接收消息。
- 持有一个指向
-
具体同事类 (
ConcreteColleagueA
和ConcreteColleagueB
):- 都继承自
Colleague
类,实现receiveMessage
方法。 - 添加了
sendMessage
方法,用于通过中介者发送消息。
- 都继承自
-
具体中介者类 (
ConcreteMediator
):- 持有
ConcreteColleagueA
和ConcreteColleagueB
的实例。 - 实现
sendMessage
方法,根据发送消息的同事对象,将消息转发给另一个同事对象。
- 持有
-
main
函数:- 创建
ConcreteMediator
实例,并设置ConcreteColleagueA
和ConcreteColleagueB
实例。 - 同事对象通过中介者发送和接收消息。
- 创建
通过这种方式,同事对象之间的复杂依赖关系被简化到通过中介者进行交互,从而提高了系统的模块化和可维护性
标签:Enable,登录,账号,void,c++,tmpuictllist,-----,按钮,设计模式 From: https://www.cnblogs.com/bwbfight/p/18248426