1. 程式人生 > 實用技巧 >設計模式之中介者模式

設計模式之中介者模式

中介者模式 Mediator

Intro

中介者模式,用一箇中介物件來封裝一系列的物件互動。
中介者使得各物件不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變他們之間的互動。

中介模式定義了一個單獨的(中介)物件,來封裝一組物件之間的互動。將這組物件之間的互動委派給與中介物件互動,來避免物件之間的直接互動。

使用場景

中介者模式一般應用於一組物件以定義良好但是複雜的方式進行通訊的場合,以及想定製一個分佈在多個類種的行為而又不想生成太多子類的場合。

優缺點

中介者模式很容易在系統中應用,也很容易在系統中誤用。當系統出現了“多對多”互動複雜的物件群時,不要急於使用中介者模式,而要先反思你的系統在設計上是不是合理。

  • 優點

    中介者(Mediator)的出現減少了各個 Colleague 的耦合,使得可以獨立地改變和複用各個 Colleague 類和 Mediator;其次,由於把物件如何協作進行了抽象,將中介作為一個獨立的概念並將其封裝在一個物件中,這樣關注的物件就從物件各自本身的行為轉移到它們之間的互動上來,也就是站在一個更巨集觀的角度去看待系統

  • 缺點

    由於 ConcreteMediator 控制了集中化,於是就把互動複雜性變為了中介者的複雜性,這就使得中介者會變得比任何一個 ConcreteColleague 都複雜

Sample

public abstract class Mediator
{
    public abstract void Send(string message, Colleague colleague);
}

public class ConcreteMediator : Mediator
{
    public Colleague Colleague1 { private get; set; }
    public Colleague Colleague2 { private get; set; }

    public override void Send(string message, Colleague colleague)
    {
        if (colleague == Colleague1)
        {
            Colleague2.Notify(message);
        }
        else
        {
            Colleague1.Notify(message);
        }
    }
}

public abstract class Colleague
{
    protected Mediator Mediator;

    protected Colleague(Mediator mediator) => Mediator = mediator;

    public abstract void Notify(string message);
}
public class ConcreteColleague1 : Colleague
{
    public ConcreteColleague1(Mediator mediator) : base(mediator)
    {
    }

    public void Send(string message)
    {
        Mediator.Send(message, this);
    }

    public override void Notify(string message)
    {
        Console.WriteLine($"同事1 得到資訊:{message}");
    }
}
public class ConcreteColleague2 : Colleague
{
    public ConcreteColleague2(Mediator mediator) : base(mediator)
    {
    }

    public void Send(string message)
    {
        Mediator.Send(message, this);
    }

    public override void Notify(string message)
    {
        Console.WriteLine($"同事2 得到資訊:{message}");
    }
}


var mediator = new ConcreteMediator();

var c1 = new ConcreteColleague1(mediator);
var c2 = new ConcreteColleague2(mediator);
mediator.Colleague1 = c1;
mediator.Colleague2 = c2;

c1.Send("吃飯了嗎?");
c2.Send("沒有呢,你打算請客?");

More

中介模式的設計思想跟中間層很像,通過引入中介這個中間層,將一組物件之間的互動關係(或者說依賴關係)從多對多(網狀關係)轉換為一對多(星狀關係)。原來一個物件要跟 n 個物件互動,現在只需要跟一箇中介物件互動,從而最小化物件之間的互動關係,降低了程式碼的複雜度,提高了程式碼的可讀性和可維護性。

中介模式的應用會帶來一定的副作用,它有可能會產生大而複雜的上帝類。

當參與者之間的互動關係錯綜複雜,維護成本很高的時候,我們才考慮使用中介模式。

Reference