第25章 世界需要和平—中介者模式
又称调停者模式
尽管将一个系统分割成许多对象通常增加了其可复用性,但是对象间相互连接的激增又会降低其可复用性。
大量的连接时的一个对象不可能在没有其它对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难。
迪米特法则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用顶一个类的某一个方法的话,可以通过
第三者转发这个调用。
中介者模式(mediator):中介者模式用一个中介对象封装一系列的对象交互。中介者使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
Mediator类,抽象中介者类
abstract class Mediator
{
public abstract void Send(string message,Colleague colleague);
}
colleague类,抽象同事类
abstract class Colleague
{
protected Mediator mediator;
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
}
ConcreteMediator类,具体中介者类
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);
}
}
}
ConcreteColleague1和ConcreteColleague2等各种同时对象
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得到消息”);
}
}
class ConcreteColleague2 : Colleague
{
public ConcreteColleague1(Mediator mediator) : base(mediator)
{ }
public void Send(string message)
{
mediator.Send(message,this);
}
public void Notify(string message)
{
Console.WriteLine(“同事2得到消息”);
}
}
客户端:
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(“没有呢,你打算请客?”);
}
25.3 安理会做中介
联合国类,相当于Mediator类
abstract class UnitedNations
{
//声明
public abstract void Declare(string message,Country colleague);
}
国家类,相当于Colleague类
//国家
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(“美国获取对方消息”);
}
}
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(“伊拉克获得对方消息”);
}
}
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,Colleague colleague)
{
if (colleague == colleague1)
{
colleague2.GetMessage(message);
}
else
{
colleague1. GetMessage(message);
}
}
}
客户端调用
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(“你咬我!”);
}
25.4 中介者模式的优缺点
中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了‘多对多’交互复杂的对象群时,不要急于使用中介者模式,而是反思你的系统设计上是否合理。
Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague和Mediator。其次由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到他们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
由于ConcreteMediator控制了集中化,于是就把交互的复杂性变成了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。
中介者模式一般应用于一组对象以定义良好但复杂的方式进行通信的场合。以及想定制一个分布在多个类中的行为,而又不想生在太多子类的场合。