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合二为一。

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责任太多了,如果它出了问题,则整个系统都会出现问题了。

4. 中介者模式的优缺点

A: 中介模式很容易在系统应用,也很容易在系统中误用。当系统出现了'多对多'交互复杂的对象群时,不要急于使用中介者模式,而要反思你的系统在设计上是不是合理。
B: 1)Mediator的出现减少各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator。2)由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
B: 由于ConcreteMediator控制了集中化,于是把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。中介者的优点来自集中控制,去缺点也会是它。
A: 中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。


yuanoung
10 声望1 粉丝

« 上一篇
责任链模式
下一篇 »
享元模式

引用和评论

0 条评论