中介者模式(Mediator)定义:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
使用场景:
- 一组对象以定义良好但是复杂的方式进行通信的场合
- 想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合
优点:
- 类之间各司其职,符合迪米特法则。
- 降低了对象之间的耦合性,使得对象易于独立地被复用。
- 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
缺点:
- 由于集中化,中介者承担了对象间交互的复杂性。当同事类越多时,中介者就会越臃肿,变得复杂且难以维护。
结构:
抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
具体中介者(Concrete Mediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
- 代码背景:美国怀疑伊拉克有核武器,威胁发动战争,联合国安理会从中调停,传递两国话语。
抽象中介者:联合国机构
abstract class UnitedNations//联合国机构 { //声明 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); } }
客户端:
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(); } }