设计模式(二十一)中介者模式

中介者模式(Mediator),用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,比如 Form 对象或 Web 页面 aspx,已经想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。

基本代码

  1 // 抽象中介者类
  2 abstract class Mediator
  3 {
  4   // 定义一个抽象的发送消息方法,得到同事对象和发送消息
  5   public abstract void Send(string message, Colleague colleague);
  6 }
  7 
  8 // 抽象同事类
  9 abstract class Colleague
 10 {
 11   protected Mediator mediator;
 12 
 13   public Colleague(Mediator mediator)
 14   {
 15     // 构造方法,得到中介者对象
 16     this.mediator = mediator;
 17   }
 18 }
 19 
 20 // 具体中介者类
 21 class ConcreteMediator : Mediator
 22 {
 23   private ConcreteColleague1 Colleague1;
 24   private ConcreteColleague2 Colleague2;
 25 
 26   public ConcreteColleague1 Colleague1
 27   {
 28     set { colleague1 = value; }
 29   }
 30 
 31   public ConcreteColleague2 Colleague2
 32   {
 33     set { colleague2 = value; }
 34   }
 35 
 36   // 根据对象做出选择判断,通知对象
 37   public override void Send(string message, Colleague colleague)
 38   {
 39     if(colleague == colleague1)
 40     {
 41       colleague2.Notify(message);
 42     }else
 43     {
 44       colleague1.Notify(message);
 45     }
 46   }
 47 }
 48 
 49 //
 50 class ConcreteColleague1 : Colleague
 51 {
 52   public ConcreteColleague1(Mediator mediator) : base(mediator)
 53   {
 54   }
 55 
 56   // 发送信息时通过中介发送
 57   public void Send(string message)
 58   {
 59     mediator.Send(message, this);
 60   }
 61 
 62   public void Notify(string message)
 63   {
 64     Console.WriteLine("同事 1 得到信息:" + message);
 65   }
 66 }
 67 
 68 //
 69 class ConcreteColleague2 : Colleague
 70 {
 71   public ConcreteColleague2(Mediator mediator) : base(mediator)
 72   {
 73   }
 74 
 75   // 发送信息时通过中介发送
 76   public void Send(string message)
 77   {
 78     mediator.Send(message, this);
 79   }
 80 
 81   public void Notify(string message)
 82   {
 83     Console.WriteLine("同事 2 得到信息:" + message);
 84   }
 85 }
 86 
 87 // 客户端
 88 static void Main(string[] args)
 89 {
 90   ConcreteMediator m = new ConcreteMediator();
 91 
 92   // 让两个具体同事类认识中介者对象
 93   ConcreteColleague1 c1 = new ConcreteColleague1(m);
 94   ConcreteColleague2 c2 = new ConcreteColleague2(m);
 95 
 96   // 让中介者认识各个具体同事类对象
 97   m.Colleague1 = c1;
 98   m.Colleague2 = c2;
 99 
100   // 具体同事类对象的发送信息都是通过中介者转发
101   c1.Send(" ");
102   c2.Send(" ");
103 
104   Console.Read();
105 }

 【例】联合国中介

基本代码

  1 // 联合国机构,相当于抽象中介者类
  2 abstract class UnitedNations
  3 {
  4   // 声明
  5   public abstract void Declare(string message, Country colleague);
  6 }
  7 
  8 // 国家类,相当于抽象同事类
  9 abstract class Country
 10 {
 11   protected UnitedNations mediator;
 12 
 13   public Country(UnitedNations mediator)
 14   {
 15     // 构造方法,得到中介者对象
 16     this.mediator = mediator;
 17   }
 18 }
 19 
 20 // 联合国安理会,具体中介者类
 21 class UnitedNationsSecurityCouncil : UnitedNations
 22 {
 23   private USA Colleague1;
 24   private Ireq Colleague2;
 25 
 26   public USA Colleague1
 27   {
 28     set { colleague1 = value; }
 29   }
 30 
 31   public Ireq Colleague2
 32   {
 33     set { colleague2 = value; }
 34   }
 35 
 36   // 重写声明方法,实现两个对象间的通信
 37   public override void Declare(string message, Country colleague)
 38   {
 39     if(colleague == colleague1)
 40     {
 41       colleague2.GetMessage(message);
 42     }else
 43     {
 44       colleague1.GetMessage(message);
 45     }
 46   }
 47 }
 48 
 49 // 美国类
 50 class USA : Country
 51 {
 52   public USA(UnitedNations mediator) : base(mediator)
 53   {
 54   }
 55 
 56   // 声明
 57   public void Declare(string message)
 58   {
 59     mediator.Declare(message, this);
 60   }
 61 
 62   // 获得消息
 63   public void GetMessage(string message)
 64   {
 65     Console.WriteLine("美国获得对方信息:" + message);
 66   }
 67 }
 68 
 69 // 伊拉克
 70 class Iraq : Country
 71 {
 72   public Iraq(UnitedNations mediator) : base(mediator)
 73   {
 74   }
 75 
 76   // 声明
 77   public void Declare(string message)
 78   {
 79     mediator.Declare(message, this);
 80   }
 81 
 82   // 获得消息
 83   public void GetMessage(string message)
 84   {
 85     Console.WriteLine("伊拉克获得对方信息:" + message);
 86   }
 87 }
 88 
 89 // 客户端
 90 static void Main(string[] args)
 91 {
 92   UnitedNationsSecurityCouncil UNNSC = new UnitedNationsSecurityCouncil();
 93 
 94   // 让两个具体同事类认识中介者对象
 95   USA c1 = new USA(UNNSC);
 96   Ireq c2 = new Ireq(UNNSC);
 97 
 98   // 让中介者认识各个具体同事类对象
 99   UNNSC.Colleague1 = c1;
100   UNNSC.Colleague2 = c2;
101 
102   // 具体同事类对象的发送信息都是通过中介者转发
103   c1.Declare(" ");
104   c2.Declare(" ");
105 
106   Console.Read();
107 }

【总结】

中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了 “多对多” 交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。

中介者模式优点:

1、Mediator 的出现减少了各个 Colleague 的耦合,使得可以独立地改变和复用各个 Colleague 类和 Mediator。

2、由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。

缺点:

由于 ConcreteMediator 控制了集中化,于是就把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个 ConcreteColleague 都复杂。

posted @ 2015-06-21 17:57  壬子木  阅读(129)  评论(0)    收藏  举报