中介者模式:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
下面举例说明多个聊天者和一个中介者:
首先定义多个接收者,每个接收者都只知道自己的行为,而不了解其他接收者的情况,但它们却都认识中介者对象
/// <summary> /// 接收者抽象类,包含一个到中介者的引用 /// </summary> public abstract class Receiver { protected Mediator mediator; public String Name { get; set; } public Receiver(Mediator mediator,string name) { this.mediator = mediator; this.Name = name; } public abstract void Receive(string message); public abstract void Send(string message,string receiverName=""); } /// <summary> /// 具体的接收者,能够调用中介者的方法,并提供方法供中介者调用 /// </summary> public class ConcreteReceiver1 : Receiver { public ConcreteReceiver1(Mediator mediator,string name) : base(mediator,name) { } public override void Send(string message,string receiverName="") { this.mediator.Send(Name+" said:" + message, this, receiverName); } public override void Receive(string message) { Console.WriteLine(Name +" receive:" + message); } } public class ConcreteReceiver2 : Receiver { public ConcreteReceiver2(Mediator mediator,string name) : base(mediator,name) { } public override void Send(string message, string receiverName="") { this.mediator.Send(Name + " said:" + message, this, receiverName); } public override void Receive(string message) { Console.WriteLine(Name + " receive:" + message); } }
下面定义中介者,它需要直到所有具体的接收者,并从具体的接收者收到消息,向其它具体的接收者发送命令
/// <summary> /// 抽象的中介者,保存了接收者的列表,能够添加或删除接收者 /// </summary> public abstract class Mediator { public List<Receiver> receiverList; public abstract void Send(string message, Receiver sender, string receiverName); public Mediator() { receiverList = new List<Receiver>(); } public void AddReceiver(Receiver receiver) { receiverList.Add(receiver); } public void RemoveReceiver(Receiver receiver) { receiverList.Remove(receiver); } } /// <summary> /// 具体的中介者对象,能够根据具体某个接收者的消息,通知某个和所有接收者 /// </summary> public class ConcreteMediator:Mediator { public override void Send(string message, Receiver sender,string receiverName="") { if (receiverName!="") { foreach (var item in receiverList) { if (item.Name==receiverName) { item.Receive(message); } } } else { foreach (var item in receiverList) { if (item != sender) { item.Receive(message); } } } } }
客户端调用代码如下,指定接受者时,只有指定的接受者收到消息,不指定接受者时,除发送者之外的所有接收者收到消息:
ConcreteMediator mediator = new ConcreteMediator(); ConcreteReceiver1 speaker1 = new ConcreteReceiver1(mediator,"Kelly"); ConcreteReceiver2 speaker2 = new ConcreteReceiver2(mediator,"Mike"); ConcreteReceiver1 speaker3 = new ConcreteReceiver1(mediator, "Stefan"); mediator.AddReceiver(speaker1); mediator.AddReceiver(speaker2); mediator.AddReceiver(speaker3); speaker1.Send("How are you?"); speaker2.Send("I'm fine"); speaker3.Send("I'm not OK", "Kelly");
执行结果如下:
Mike receive:Kelly said:How are you?
Stefan receive:Kelly said:How are you?
Kelly receive:Mike said:I'm fine
Stefan receive:Mike said:I'm fine
Kelly receive:Stefan said:I'm not OK
中介者模式很容易在系统中应用,也很容易在系统中误用。它的优点是中介者的出现减少了各接收者的耦合,使得它们可以独立改变和复用。由于把对象如何协作进行了抽象,将中介者作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。同时由于中介者控制的集中化,于是就把交互复杂性变成了中介者的复杂性,这就是中介者变得比任何一个接收者都复杂,也更加容易出现问题。