首页 > 编程语言 >c/c++设计模式-----中介者模式

c/c++设计模式-----中介者模式

时间:2024-06-14 18:37:26浏览次数:27  
标签:Enable 登录 账号 void c++ tmpuictllist ----- 按钮 设计模式

中介者模式概念:

在软件设计中,中介者模式(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;
}
  1. 抽象中介者类 (Mediator):

    • 定义了一个接口 sendMessage,用于传递消息。
  2. 抽象同事类 (Colleague):

    • 持有一个指向 Mediator 的指针。
    • 定义了一个纯虚函数 receiveMessage 用于接收消息。
  3. 具体同事类 (ConcreteColleagueAConcreteColleagueB):

    • 都继承自 Colleague 类,实现 receiveMessage 方法。
    • 添加了 sendMessage 方法,用于通过中介者发送消息。
  4. 具体中介者类 (ConcreteMediator):

    • 持有 ConcreteColleagueA 和 ConcreteColleagueB 的实例。
    • 实现 sendMessage 方法,根据发送消息的同事对象,将消息转发给另一个同事对象。
  5. main 函数:

    • 创建 ConcreteMediator 实例,并设置 ConcreteColleagueA 和 ConcreteColleagueB 实例。
    • 同事对象通过中介者发送和接收消息。

通过这种方式,同事对象之间的复杂依赖关系被简化到通过中介者进行交互,从而提高了系统的模块化和可维护性

标签:Enable,登录,账号,void,c++,tmpuictllist,-----,按钮,设计模式
From: https://www.cnblogs.com/bwbfight/p/18248426

相关文章

  • 公有云---云主机管理
    虚拟私有云1.华为云控制台华为云所有资源配置都在控制台完成(区域)相同区域中的云主机是可以相互连通的,选择离自己比较近的区域可以减少网络延时虚拟私有云是华为的网络配置入口,我们在配置其他服务之前必须先定义网络配置VPC网络与子网安全组安全组是云主机的防火墙入......
  • 核心(Hutool-core)语言特性(二进码十进数-BCD)
    介绍BCD码(Binary-CodedDecimal)亦称二进码十进数或二-十进制代码,BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。这种编码技巧最常用于会计系统的设计里,因为会计制度经常需要对很长的数字串作准确的计算。相对于一般的浮点式......
  • 【C++】类的默认成员函数
    类的默认成员函数类的六个默认成员函数构造函数构造函数的概念构造函数的特性析构函数析构函数的概念析构函数的特性构造函数与析构函数的调用顺序拷贝构造拷贝构造的概念拷贝构造的特性赋值运算符重载运算符重载赋值运算符重载前置++与后置++重载输入输出流重载const......
  • 微信小程序源码-基于Java后端的家庭大厨系统的计算机毕业设计(附源码+论文)
    大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。......
  • 微信小程序源码-基于Java后端的家庭财务管理系统的计算机毕业设计(附源码+论文)
    大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【贪心/脑筋急转弯】2
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明示例三......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【二分查找】2024D-部
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例输入输出说明解题思路代码pythonjavacpp时......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【DFS】2024D-计算三
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上全网独家的欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述:输入描述输出描述示例一输入输出说明示例二输入输出说明示例三......
  • 核心(Hutool-core)工具类(社会信用代码工具-CreditCodeUtil)
    介绍法人和其他组织统一社会信用代码制度,相当于让法人和其他组织拥有了一个全国统一的“身份证号”。规则如下:第一部分:登记管理部门代码1位(数字或大写英文字母)第二部分:机构类别代码1位(数字或大写英文字母)第三部分:登记管理机关行政区划码6位(数字)第四部分:主体标识码(......
  • 核心(Hutool-core)工具类(信息脱敏工具-DesensitizedUtil)
    介绍在数据处理或清洗中,可能涉及到很多隐私信息的脱敏工作,因此Hutool针对常用的信息封装了一些脱敏方法。现阶段支持的脱敏数据类型包括:用户id中文姓名身份证号座机号手机号地址电子邮件密码中国大陆车牌,包含普通车辆、新能源车辆银行卡整体来说,所谓脱敏就是隐藏掉信......