• 中介者模式


    一、简介
    1. 定义
    用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
    2. 应用场景
    适用于系统中大量的对象需要相互的依赖,并且彼此间的依赖关系复杂混乱,此时在重构过程中,可以用一个中间类来管理这些对象之间的依赖关系。
    3.优缺点
    优点:
    将多个互相依赖的类进行解耦,使得这些有交互的对象松耦合;
    增加交互对象时,只需要在中介类中进行修改即可,不需要变动其他的对象实现;
    缺点:
    中介类可能会变得复杂,甚至会发展到功能庞大,违反类的单一职责。
    4. 类图


    二、 代码示例
    1. 场景简介
    在组队枪战游戏中,突击小队需要通过通讯设备来完成战术的安排与实施,队长主要负责下达命令,队员根据战况请求支援。

    #ifndef MEDIATOR_H
    #define MEDIATOR_H
    
    #include <QString>
    #include <QDebug>
    #include <QMap>
    
    class IMediator;
    
    class IUser
    {
    public:
        IUser(QString name)
            : m_name(name)
        {};
        virtual ~IUser() {};
    
        inline QString name() { return m_name; };
        virtual void send(QString msg, IMediator *mediator) = 0;
        virtual void notify(QString msg) = 0;
    
    private:
        QString            m_name;
    };
    
    class IMediator
    {
    public:
        IMediator() {};
        virtual ~IMediator() {};
    
        virtual void registeUser(IUser *user)
        {
            QString name = user->name();
            if (!m_userMap.contains(name))
            {
                m_userMap.insert(name, user);
            }
        };
        virtual void unregisterUser(IUser *user)
        {
            m_userMap.remove(user->name());
        };
        virtual void sendMsg(QString msg, IUser *sender) = 0;
    
    protected:
        QMap<QString, IUser*>        m_userMap;
    };
    
    class GameMediator : public IMediator
    {
    public:
        GameMediator() {};
        virtual ~GameMediator() {};
    
        virtual void sendMsg(QString msg, IUser *sender)
        {
            foreach (IUser* user, m_userMap)
            {
                if (user->name() != sender->name())
                {
                    user->notify(msg);
                }
            }
        };
    };
    
    class UserImp : public IUser
    {
    public:
        UserImp(QString name)
            : IUser(name)
        {};
        virtual ~UserImp() {};
    
        virtual void send(QString msg, IMediator *mediator)
        {
            if (nullptr != mediator)
            {
                mediator->sendMsg(msg, this);
            }
        };
        virtual void notify(QString msg)
        {
            qDebug() << name() << "receive msg: " << msg;
        };
    };
    
    #if 1
    
    #define FREE_OBJ(obj)        if (nullptr != (obj)){delete (obj); (obj) = nullptr;}
    
    void main()
    {
        IMediator *mediator = new GameMediator;
    
        UserImp *captain = new UserImp("Game Captain");
        UserImp *playerA = new UserImp("XiaoMing");
        UserImp *playerB = new UserImp("XiaoQiang");
    
        mediator->registeUser(captain);
        mediator->registeUser(playerA);
        mediator->registeUser(playerB);
    
        captain->send("Ready?", mediator);
    
        playerA->send("Help!", mediator);
    
        FREE_OBJ(mediator);
        FREE_OBJ(captain);
        FREE_OBJ(playerA);
        FREE_OBJ(playerB);
    
        getchar();
    }
    
    #endif // 1
    
    #endif // !MEDIATOR_H
  • 相关阅读:
    布隆过滤器
    springboot+redis实现分布式锁
    springboot+redis实现消息队列
    工作启示文章收藏
    redis常用命令
    前方的路
    分布式系统中对cookie和session的思考
    用Markdown来写自由书籍-开源技术的方案
    Centos 7.0添加yum本地安装源
    爹地,我找到了!15个极好的Linux find命令示例
  • 原文地址:https://www.cnblogs.com/yuemw/p/10211657.html
Copyright © 2020-2023  润新知