中介者模式(Mediator):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互
角色
Mediator抽象中介者角色
抽象中介者角色定义统一的接口,用于各同事角色之间的通信
Concrete Mediator具体中介者角色
具体中介者橘色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
Colleague同事角色
每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为,与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法。
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); } } }CollcreteColleague1和CollcreteColleague2等各种同事对象
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); } }客户端代码
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(); }
就用前几年的美国与伊拉克的战争为例吧。
伊拉克战争,是以英美军队为主的联合部队在2003年3月20日对伊拉克发动的军事行动,美国以伊拉克藏有大规模杀伤性武器并暗中支持恐怖分子为由,绕开联合国安理会,单方面对伊拉克实施军事打击。实质上是借反恐时机,以伊拉克拒绝交出子虚乌有的生化武器为借口,趁机清除反美政权的一战争。由于这次战争实际上是1990年海湾战争的继续,所以,这次战争也被称为“第二次海湾战争”。
由于各国之间的利益不同,所以矛盾冲突时难免的,但如果有这样一个组织,由各国的代表组成,用来维护国际和平与安全,解决国际间的经济、社会、文化和人道主义性质的问题,不就很好嘛?于是乎联合国就充当了这个角色。
联合国机构(相当于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; } }美国类 相当于ConcreteColleaguel 类
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); } }伊拉克类 相当于ConcreteColleague2类
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); } }联合国安理会 相当于ConcreteMediator 类
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); } } }客户端代码
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(); }
1.一组定义良好的对象,现在要进行复杂的通信。
2.定制一个分布在多个类中的行为,而又不想生成太多的子类。
中介者模式一般应用于一组对象已定义良好但是以复杂的方式进行通信的场合,一般情况下,中介者模式很容易在系统中使用,但也容易在系统里误用,当系统出现了多对多交互复杂的对象群时,先不要急于使用中介者模式,而是要思考一下是不是系统设计有问题。
另外,由于中介者模式把交互复杂性变成了中介者本身的复杂性,所以说中介者对象会比其它任何对象都复杂。