中介者模式

1. 世界須要和平

A: 儘管將一個系統分割成許多對象一般能夠增長其可複用性,可是對象間的互相鏈接的激增又會下降其可複用性。
B: 由於大量的鏈接使得一個對象不可能在沒有其餘對象的支持下工做,系統表現爲一個不可分割的總體,全部,對系統的行爲進行任何較大的改動就十分困難了。
B: 迪米特原則,若是兩個類沒必要彼此直接通訊,那麼這兩個類就不該當發生之間的相互做用。若是其中一個類須要調用另外一個類的某一個方法的話,能夠經過第三者轉發這個調用。
A: 經過中介者對象,能夠將系統的網狀結構變成以中介者的星型結構,每一個具體對象再也不經過直接的聯繫與另外一個對象發生相互做用,而是經過'中介者'對象與另外一個對象發生相互做用。中介者對象的設計,使得系統的結構不會由於新對象的引入形成大量的修改工做。安全

2. 中介者模式

用一箇中介對象來封裝一系列的對象交互。中介者使得各對象不須要顯式地互相引用,從而使得耦合鬆散,並且能夠獨立的改變它們之間的交互。

圖1

class Program
{
    static void Main(string[] args)
    {
        ConcreteMediator m = new ConcreteMediator();

        ConcreteColleague1 c1 = new ConcreteColleague1(m);
        ConcreteColleague2 c2 = new ConcreteColleague2(m);

        m.Colleague1 = c1;
        m.Colleague2 = c2;

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

        Console.Read();
    }
}

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

class ConcreteMediator : Mediator
{
    private ConcreteColleague1 colleague1;
    private ConcreteColleague2 colleague2;

    public ConcreteColleague1 Colleague1
    {
        set { colleague1 = value; }
    }

    public ConcreteColleague2 Colleague2
    {
        set { colleague2 = value; }
    }

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

abstract class Colleague
{
    protected Mediator mediator;

    public Colleague(Mediator mediator)
    {
        this.mediator = mediator;
    }
}

class ConcreteColleague1 : Colleague
{
    public ConcreteColleague1(Mediator mediator)
        : base(mediator)
    {

    }

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

    public void Notify(string message)
    {
        Console.WriteLine("同事1獲得信息:" + message);
    }
}

class ConcreteColleague2 : Colleague
{
    public ConcreteColleague2(Mediator mediator)
        : base(mediator)
    {
    }

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

    public void Notify(string message)
    {
        Console.WriteLine("同事2獲得信息:" + message);
    }
}

A: 因爲有了mediator,使得ConcreteColleague1和ConcreteColleague在發送消息和接收信息時實際上是經過中介者來完成,這就減小了它們之間的耦合度了。
B: 聯合國究竟是Mediator仍是ConcreteMediator呢?
A: 這取決於將來是否有可能擴展中介者對象,好比你以爲聯合國除了安理會,還有沒有可能有其餘機構存在呢?
A: 若是不存在擴展的狀況,那麼Mediator能夠與ConcreteMediator合二爲一。ide

3, 安理會作中介

圖2

class Program
{
    static void Main(string[] args)
    {
        UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();

        USA c1 = new USA(UNSC);
        Iraq c2 = new Iraq(UNSC);

        UNSC.Colleague1 = c1;
        UNSC.Colleague2 = c2;

        c1.Declare("不許研製核武器,不然要發動戰爭!");
        c2.Declare("咱們沒有核武器,也不怕侵略。");

        Console.Read();
    }
}

//聯合國機構
abstract class UnitedNations
{
    /// <summary>
    /// 聲明
    /// </summary>
    /// <param name="message">聲明信息</param>
    /// <param name="colleague">聲明國家</param>
    public abstract void Declare(string message, Country colleague);
}

//聯合國安全理事會
class UnitedNationsSecurityCouncil : UnitedNations
{
    private USA colleague1;
    private Iraq colleague2;

    public USA Colleague1
    {
        set { colleague1 = value; }
    }

    public Iraq Colleague2
    {
        set { colleague2 = value; }
    }

    public override void Declare(string message, Country colleague)
    {
        if (colleague == colleague1)
        {
            colleague2.GetMessage(message);
        }
        else
        {
            colleague1.GetMessage(message);
        }
    }
}

//國家
abstract class Country
{
    protected UnitedNations mediator;

    public Country(UnitedNations mediator)
    {
        this.mediator = mediator;
    }
}

//美國
class USA : Country
{
    public USA(UnitedNations mediator)
        : base(mediator)
    {

    }
    //聲明
    public void Declare(string message)
    {
        mediator.Declare(message, this);
    }
    //得到消息
    public void GetMessage(string message)
    {
        Console.WriteLine("美國得到對方信息:" + message);
    }
}

//伊拉克
class Iraq : Country
{
    public Iraq(UnitedNations mediator)
        : base(mediator)
    {
    }

    //聲明
    public void Declare(string message)
    {
        mediator.Declare(message, this);
    }
    //得到消息
    public void GetMessage(string message)
    {
        Console.WriteLine("伊拉克得到對方信息:" + message);
    }

}

B: 儘管這樣的設計能夠減小ConcreteColleague類之間的耦合,但這又使得ConcreteMediator責任太多了,若是它出了問題,則整個系統都會出現問題了。this

4. 中介者模式的優缺點

A: 中介模式很容易在系統應用,也很容易在系統中誤用。當系統出現了'多對多'交互複雜的對象羣時,不要急於使用中介者模式,而要反思你的系統在設計上是否是合理。
B: 1)Mediator的出現減小各個Colleague的耦合,使得能夠獨立地改變和複用各個Colleague類和Mediator。2)因爲把對象如何協做進行了抽象,將中介做爲一個獨立的概念並將其封裝在一個對象中,這樣關注的對象就從對象各自自己的行爲轉移到它們之間的交互上來,也就是站在一個更宏觀的角度去看待系統。
B: 因爲ConcreteMediator控制了集中化,因而把交互複雜性變爲了中介者的複雜性,這就使得中介者會變得比任何一個ConcreteColleague都複雜。中介者的優勢來自集中控制,去缺點也會是它。
A: 中介者模式通常應用於一組對象以定義良好可是複雜的方式進行通訊場合,以及想定製一個分佈在多個類中的行爲,而又不想生成太多的子類的場合。spa

相關文章
相關標籤/搜索