0. 简介

中介者模式和命令模式类似,都有着一层中间层来作为沟通的渠道,只是中介者模式使用了Mediator来实现实现更新函数changed。而在命令模式中使用Invoke作为最上层,用于管理具体类的操作,从而对接收者增删。简而言之,命令模式在发送者和请求者之间建立单向连接,使请求者可以调用发送者的不同方法。中介者清除了发送者和请求者之间的直接连接, 强制它们通过一个中介对象进行间接沟通。

1. 中介者模式示意图

中介者模式是一种行为设计模式, 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。用一个中介者对象封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而减小耦合。
在这里插入图片描述
抽象中介者(Mediator):抽象中介者角色定义统一的接口,用于各同事角色之间的通信。

抽象同事类(Colleague ):每一个同事角色都知道中介者角色,而且与其它的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分两种:一种是同事本身行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为,与其它同事类或者中介者没有任何依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法。

具体中介者类(Concrete Mediator):具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。

具体同事类(Concrete Colleague):这里以ConcreteColleague1为例,ConcreteColleague2不再赘述。

2. 示例程序

从上述的结构中我们可以看出中介者模式应该是在多个类相互耦合,形成网状结构时使用,通过将网状结构分离为星型结构,从而实现减少类间依赖,降低了耦合,从而实现符合迪米特原则。

采用这种方式, 中介者模式让你能在单个中介者对象中封装多个对象间的复杂关系网。 类所拥有的依赖关系越少, 就越易于修改、 扩展或复用。

#include <iostream>

using namespace std;

class Colleague;

//定义一个中介者接口,包含对象改变所需调用函数。
class Mediator
{
public :
    virtual ~Mediator()
    {

    }
    virtual void changed(Colleague *)=0;

};

//定义"同事"类接口,初始化需要一个中介者对象,并通过该类更新另外一个"同事"
class Colleague
{
public :
    //初始化中介者类对象
    Colleague(Mediator * mediator)
    {
        this->mediator =mediator;
    }
    //更新另外一个类
    virtual void changed()
    {
        mediator->changed(this);
    }
private:
    Mediator *mediator;
};

//具体的同事类1
class ConcreteColleague1 :public Colleague
{
public:
    ConcreteColleague1(Mediator * mediator):Colleague(mediator)
    {
    }
    void update()
    {
        cout<<"update ConcreteColleague1 from ConcreteColleague2"<<endl;
    }
};
//具体的同事类2
class ConcreteColleague2 :public Colleague
{
public :
    ConcreteColleague2(Mediator * mediator):Colleague(mediator)
    {
    }
    void update()
    {
        cout<<"update ConcreteColleague2 from ConcreteColleague1"<<endl;
    }
};

//具体的中介者类,实现更新函数changed。
class ConcreteMediator :public Mediator
{
private:
    ConcreteColleague1 * colleague1;
    ConcreteColleague2 * colleague2;
public:
    void setColleague1(ConcreteColleague1 * colleague)
    {
        colleague1 = colleague;
    }
    void setColleague2(ConcreteColleague2 * colleague)
    {
        colleague2 = colleague;
    }
    ConcreteMediator()
    {
        //colleague1 = new ConcreteColleague1(this);

    }
    ~ConcreteMediator()
    {

    }
    virtual void changed(Colleague* colleague)
    {
        if(colleague == colleague1)
        {
            colleague2->update();
        }
        else if(colleague == colleague2)
        {
            colleague1->update();
        }
        else;
    }

};
main()
{
    ConcreteMediator concreteMediator;
    ConcreteColleague1  colleague1(&concreteMediator);
    ConcreteColleague2  colleague2(&concreteMediator);
    concreteMediator.setColleague1(&colleague1);
    concreteMediator.setColleague2(&colleague2);
    //"同事1"通过中介者更新"同事2"
    colleague1.changed();
    //"同事2"通过中介者更新"同事1"
    colleague2.changed();

}

3. 中介者模式与命令模式

3.1 中介者模式

中介者模式用于处理多个类高耦合的场景,类似于星型拓扑结构,在该结构中抽象出一个中介者,并配备同事类,实现不同的业务逻辑。
在这里插入图片描述
命令模式的思路:中介者-同事-业务实现类。
抽象中介者定义统一的接口,用于各同事角色之间通信,具体中介者用于协调各同事角色最终的协作,必须依赖各个同事,同事角色不能与其他同事类有依赖,如果需要的话,必须通过中介者才能完成。

3.2 命令模式

命令模式是一种高内聚的设计模式:
在这里插入图片描述
命令模式的思路:client-Invoker-command-receiver。这个模式尽量保证client少跟receiver打交道,该模式的优点是架构清晰明了,但是有一个缺点是如果命令很多的话,那么继承command的子类也会非常多。

4. 中介者模式的优缺点

作为经常使用的MVC框架,其中C(Contorller控制器)是M(Model模型)和V(View视图)的中介者。这也让我们看到了中介者在管理庞大内容时的潜力。

总的来说,中介者模式降低了类的复杂度,将一对多转化成了一对一,同时实现了各个类之间的解耦。

在这里插入图片描述

5. 参考链接

https://blog.csdn.net/achina2011jy/article/details/103910509

https://www.cnblogs.com/adamjwh/p/10959987.html

https://refactoringguru.cn/design-patterns/mediator

https://www.cnblogs.com/hebaichuanyeah/p/6091506.html