<1>在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化;
<2>在这种情况下,我们可使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
——《设计模式》GoF
<1>联合国机构下设安理会,专门负责各国之间的调停和协调工作;
<2>不同国家之间通过联合国机构进行事务声明。
namespace Test
{
//Mediator
public abstract class 联合国机构
{
protected System.Collections.Generic.List<国家> 成员国 = new List<国家>();
public void 接收新成员国(国家 colleague)
{
if (!this.成员国.Contains(colleague))
{
this.成员国.Add(colleague);
}
}
public void 开除成员国(国家 colleague)
{
if (this.成员国.Contains(colleague))
{
this.成员国.Remove(colleague);
Console.WriteLine("<{0}>:开除成员国:{1}", this, colleague);
}
}
public abstract void 发表声明(string 内容, 国家 发表者);
}
//ConcreteMediator
public class 安理会 : 联合国机构
{
public override void 发表声明(string 内容, 国家 发表者)
{
foreach (国家 colleague in base.成员国)
{
if (colleague != 发表者)
{
colleague.接收声明(内容, 发表者);
}
}
}
}
//Colleague
public abstract class 国家
{
protected 联合国机构 _协调人;
public 国家(联合国机构 mediator)
{
this._协调人 = mediator;
mediator.接收新成员国(this);
Console.WriteLine("{0}在{1}\t加入联合国", this.ToString(), DateTime.Now);
}
public virtual void 发表声明(string 内容)
{
Console.WriteLine("<{0}>发表声明:\r\n\t{1}", this, 内容);
this._协调人.发表声明(内容, this);
}
public virtual void 接收声明(string 内容, 国家 发表者)
{
Console.WriteLine("{0}收到<{1}>发表的声明:\r\n\t{2}\t时间:{3}", this, 发表者, 内容, DateTime.Now);
}
}
public class 美国 : 国家
{
public 美国(联合国机构 meidator) : base(meidator)
{
}
public override void 接收声明(string 内容, 国家 发表者)
{
base.接收声明(内容, 发表者);
if (内容.Contains("核武器"))
{
Console.WriteLine("!!!!警报:FBI开始对{0}进行全程监控", 发表者);
}
}
}
public class 伊拉克 : 国家
{
public 伊拉克(联合国机构 meidator) : base(meidator)
{
}
public override void 接收声明(string 内容, 国家 发表者)
{
base.接收声明(内容, 发表者);
if (内容.Contains("核武器"))
{
Console.WriteLine("<{0}>说:额是冤枉的,{1}不要诬陷好人", this, 发表者);
}
}
public override void 发表声明(string 内容)
{
if (内容.Contains("恐怖活动"))
{
Console.WriteLine("<{0}>:******低调,低调,低调*******", this);
}
base.发表声明(内容);
}
}
internal class Program
{
static void Main(string[] args)
{
联合国机构 mediator = new 安理会(); //调停者mediator
国家 usa = new 美国(mediator); //colleague
国家 iraq = new 伊拉克(mediator); //colleague
usa.发表声明("禁止研制核武器和大规模杀伤武器,否则就开打!"); //不直接与iraq耦合
iraq.发表声明("严正声明:本国没有研制任何核武器!"); //不直接与usa耦合
iraq.发表声明("别欺国太甚,否则本国会悍然来次恐怖活动!");
mediator.开除成员国(iraq); //iraq不听话,开除之
usa.发表声明("再次声明:禁止研制核武器和大规模杀伤武器,否则就开打!"); //iraq再也接收不到了
Console.ReadLine();
}
}
}
<1>中介者角色集中了太多的责任,所有有关的同事对象都要由它来控制;
<2>建议在使用中介者模式的时候注意控制中介者角色的大小。
<1>将同事角色解耦;
<2>系统结构改善:提高了原有系统的可读性、简化原有系统的通信协议——将原有的多对多变为一对多、提高了代码的可复用性;
<3>“与其多个人累,不如我一个人来累"
<1>多个对象互相关联交互的情况,对象之间维持一种复杂的引用关系;
<2>一组对象以定义良好但是复杂的方式进行通信,产生了混乱的依赖关系,也导致对象难以复用。
<1>将多个对象间复杂的关联关系解耦,Mediator模式将多个对象间的控制逻辑进行集中管理,变“多个对象互相关联”为“多个对象和一个中介者关联”,简化了系统的维护,抵御了可能的变化;
<2>随着控制逻辑的复杂化,Mediator具体对象的实现可能相当复杂。这时候可以对Mediator对象进行分解处理;
<3>Façade模式是解耦系统外到系统内(单向)的对象关联关系;Mediator模式是解耦系统内各个对象之间(双向)的关联关系。