1. 程式人生 > >二十三種設計模式[17] - 中介者模式(Mediator Pattern)

二十三種設計模式[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)