二十三种设计模式[17] - 中介者模式(Mediator Pattern)

前言

       在开发软件的过程中,我们通常会将类设计的比较单纯,使其复用性更高。但类间的相互引用又使得类本身在没有其他类的支持下不能正常工作,导致其复用性降低。所以为了提高类的复用性我们需要尽可能的减少对其它类的引用,也就是说我们常说的解耦。中介者模式,顾名思义,就是存在一个类似中介的角色,类与类之间不直接交互而是通过中介进行间接的交互,也就意味着类与类之间不需要存在显示的引用,以达到松耦合的目的。

       中介者模式,对象行为型模式的一种。在《设计模式 - 可复用的面向对象软件》一书中将之描述为“ 用一个中介对象来封装一些列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互 ”。

结构

Mediator_1

  • Mediator(抽象中介者):用来定义各同事对象间的交互,只有一个实现时无存在意义;
  • ConcreteMediator(具体中介者):实现中介者接口,保留各个同事对象的引用并实现各同事对象间的业务交互;
  • Colleague(抽象同事类):所有具体同事类的公共接口,可有可无(因为无法保证所有同事类都存在某些函数)
  • ConcreteColleague(具体同事类):具体的业务对象,只实现了本身关心的业务并且保留了中介者的引用,通过中介者与其它业务对象交互;

示例

Mediator_2

public class ColleagueA
{
    private Mediator MediatorObj { set; get; }

    public ColleagueA(Mediator mediator)
    {
        this.MediatorObj = mediator;
    }

    public void OperationA()
    {
        Console.WriteLine("ConcreteColleagueA.Operation");
    }

    public void OperationB()
    {
        Console.Write("[ConcreteColleagueA]:");

        if (this.MediatorObj != null)
        {
            this.MediatorObj.OperationB();
        }
    }
}

public class ColleagueB
{
    private Mediator MediatorObj { set; get; }

    public ColleagueB(Mediator mediator)
    {
        this.MediatorObj = mediator;
    }

    public void OperationA()
    {
        Console.Write("[ConcreteColleagueB]:");

        if (this.MediatorObj != null)
        {
            this.MediatorObj.OperationA();
        }
    }

    public void OperationB()
    {
        Console.WriteLine("ConcreteColleagueB.Operation");
    }
}

public class ColleagueC
{
    public void Operation()
    {
        Console.WriteLine("ConcreteColleagueC.Operation");
    }
}

public class ColleagueD
{
    private Mediator MediatorObj { set; get; }

    public ColleagueD(Mediator mediator)
    {
        this.MediatorObj = mediator;
    }

    public void Operation()
    {
        Console.Write("[ConcreteColleagueD]:");

        if (this.MediatorObj != null)
        {
            this.MediatorObj.OperationC();
        }
    }
}

public class Mediator
{
    public ColleagueA ColleagueAObj { set; private get; }
    public ColleagueB ColleagueBObj { set; private get; }
    public ColleagueC ColleagueCObj { set; private get; }

    public void OperationA()
    {
        if(this.ColleagueAObj != null)
        {
            this.ColleagueAObj.OperationA();
        }
    }

    public void OperationB()
    {
        if (this.ColleagueBObj != null)
        {
            this.ColleagueBObj.OperationB();
        }
    }

    public void OperationC()
    {
        if (this.ColleagueCObj != null)
        {
            this.ColleagueCObj.Operation();
        }
    }
}

static void Main(string[] args)
{
    Mediator.Mediator mediator = new Mediator.Mediator();
    ColleagueA colleagueA = new ColleagueA(mediator);
    ColleagueB colleagueB = new ColleagueB(mediator);
    ColleagueC colleagueC = new ColleagueC();
    ColleagueD colleagueD = new ColleagueD(mediator);

    mediator.ColleagueAObj = colleagueA;
    mediator.ColleagueBObj = colleagueB;
    mediator.ColleagueCObj = colleagueC;

    colleagueA.OperationB();
    colleagueB.OperationA();
    colleagueD.Operation();
    Console.ReadKey();
}

image

补充

  • 中介者模式在MVC中的应用

       我们都知道在MVC(Model-模型,View-视图,Controller-控制器)中一个视图的展示需要一个或多个模型的支撑,但模型与视图并不直接交互,而是通过控制器间接交互,也就是说在MVC中,控制器充当的就是一个中介者角色。

  • 中介者模式与外观模式

       中介者模式与外观模式(Facade Pattern)比较相似,比如它们都是通过一个中间类去调用其它类。但外观模式是单向的,即Facade向子系统中的类发出请求而该类则不能向Facade发出请求,并且外观模式的核心在于将一个系统对外提供的操作封装到一个类中,使用户使用起来更加方便。而中介者模式的核心目的在于将类与其依赖类解耦,并且它的调用是双向的,Colleague既可以向Mediator发出请求,Mediator也可以向Colleague发出请求。

总结

       中介者模式能够帮助我们提高类的复用性,当类与其它类的交互业务改变时只需要增加新的中介者即可,复合开闭原则。一个类将其与外界的交互逻辑封装到中介者时能够使它们更加单纯,即类只关心自身的业务实现而中介者只需要关心各业务的交互即可,复合迪米特原则。由于中介者封装了类与类的交互逻辑,也使得它变得非常复杂难以维护。


       以上,就是我对中介者模式的理解,希望对你有所帮助。

       示例源码:https://gitee.com/wxingChen/DesignPatternsPractice

       系列汇总:https://www.cnblogs.com/wxingchen/p/10031592.html

       本文著作权归本人所有,如需转载请标明本文链接(https://www.cnblogs.com/wxingchen/p/10090551.html)

posted @ 2018-12-09 11:27  王兴Chen  阅读(191)  评论(0编辑  收藏  举报