C#面向对象设计模式纵横谈 学习笔记17 Mediator 中介者模式(行为型模式)

意图

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

Mediator模式解决了一个问题,多个类相互引用相互,相互影响,这时候类的关系模型是复杂的,一个类对象的变化会导致其他类对象的变化,这种场景有点连锁反应的意思。下面有一段代码

  1. class CutMenuItem
  2.     {
  3.         TextArea textArea;
  4.         ClipBorad clipBorad;
  5.         ToolBarButton toolBarButton;
  6.         
  7.         public void Click()
  8.         {  
  9.             string text = textArea.SelectedText;
  10.             textArea.RemoveSelectionText();
  11.             clipBorad.SetData(text);
  12.             
  13.             toolBarButton.EnabledPasteButton();
  14.         }
  15.     }
  16.     class TextArea
  17.     {
  18.         ClipBorad clipBoard;
  19.         ToolBarButton toolBarButton;
  20.         CutMenuItem cutMenuItem;
  21.         
  22.         internal void RemoveSelectionText()
  23.         {
  24.             
  25.         }
  26.     }
  27.     
  28.     class ClipBorad
  29.     {
  30.         ToolBarButton toolBarButton;
  31.         CutMenuItem cutMenuItem;
  32.         TextArea textArea;
  33.         internal void SetData(string text)
  34.         {
  35.             
  36.         }
  37.     }
  38.     
  39.     class ToolBarButton
  40.     {
  41.         ClipBorad clipBorad;
  42.         CutMenuItem cutMenuItem;
  43.         TextArea textArea;
  44.         
  45.         internal void EnabledPasteButton()
  46.         {
  47.         }
  48.     }

上面有四个类:菜单、文本框、按钮、剪贴板,每个类里面都包含其他三个类的引用。当每个类的某个方法被调用时,会连锁的引起其他三个类的对象的方法的调用。如果我们按照这种方式来写的话,如果类比较多,我们会陷入一种混乱状态。我们需要一种设计模式,将他们进行解藕。因此我们使用Mediator设计模式

  1. abstract class Mediator
  2.     {
  3.         public abstract void Notify();
  4.         public virtual void AddElement(Element element)
  5.         {
  6.             list.Add(element);
  7.         }
  8.         
  9.         List<Element> list = new List<Element>();
  10.     }
  11.     
  12.     abstract class Element
  13.     {
  14.         Mediator mediator;
  15.         public Element(Mediator mediator)
  16.         {
  17.             this.mediator = mediator;
  18.             this.mediator.AddElement(this);
  19.         }
  20.         
  21.         public virtual void OnChange()
  22.         {
  23.             
  24.         }
  25.     }
  26.     
  27.     class TextArea : Element
  28.     {
  29.         public TextArea(Mediator mediator) : base(mediator)
  30.         {
  31.             
  32.         }
  33.         
  34.         public void Process()
  35.         {
  36.             OnChange();
  37.         }
  38.     }
  39.     
  40.     class CutMenuItem : Element
  41.     {
  42.         public CutMenuItem(Mediator mediator) : base(mediator)
  43.         {
  44.         }
  45.         
  46.         public void Click()
  47.         {
  48.             OnChange();
  49.         }
  50.     }
  51.     
  52.     class ClipBoard : Element
  53.     {
  54.         public ClipBoard(Mediator mediator) : base(mediator)
  55.         {
  56.             
  57.         }
  58.         
  59.         public void Invoke()
  60.         {
  61.             OnChange();            
  62.         }
  63.      
  64.     }
  65.     
  66.     class ToolBarButton : Element
  67.     {
  68.         public ToolBarButton(Mediator mediator) : base(mediator)
  69.         {
  70.         }
  71.     
  72.         public void Click()
  73.         {
  74.             OnChange();
  75.         }
  76.     }
  77.     class ConcreteMediator : Mediator
  78.     {
  79.         public override void Notify()
  80.         {
  81.             
  82.         } 
  83.     }

 

在代码里面我们抽象了Mediator类,他有一个List的内部成员用来保存按钮、菜单等对象,有一个抽象方法Notify。我们又抽象了一个Element类,这个类有一个构造函数将指定的中介者保存在内部成员里面,并将自己加入到Mediator对象的List列表里。在Element类里还有一个OnChange的虚方法,可由派生类重写。

菜单、按钮、剪贴板、文本框都继承Element类。那么我们在实例化菜单等对象的时候,将他们几种在了一个mediator对象的List里。也就是说,我们在菜单等对象构造的时候我们就将它们转换到mediator里面去了,这就是在解藕。那当我们的菜单等对象动作的时候,我们就可以直接调用基类的OnChange方法,那么我们就可以在Element类的OnChange方法里面遍历mediator里面的List中的元素来调用对应的方法。这里有一个问题,我们为什么要抽象Mediator,我们完全可以不用抽象Mediator,直接可以用一个具体的类来实现,但是,这是在理想的情况,我们不是简单的关联关系,我们不会仅仅只有四个类型进行关联,我们可能有很多其他的对象需要关联,如果我们直接写到一个具体的类里面,那么我们的Notify方法会相当的复杂,会写很多if语句进行判断。比如说当按钮点击,我们调用List里面的ABC三个对象的方法,当菜单点击,我们会调用BCD三个对象的另外的方法,如果这样扩展下去,Notify方法将相当庞大。所以,我们可以将mediator类进行抽象,由ConcreteMediator类来实现各自的具体的逻辑,比如说当按钮点击,我可以知道这是一个联动操作的mediator,将他封装成一个类,在实现的Notify方法里面可以调用ABC的方法,当菜单点击我们可以实现另外一个mediator类,在他的Notify方法里,调用BCD的方法。

如果一组接口相对稳定的对象之间的依赖关系错综复杂,依赖关系难以维护,或者会发生变动可以考虑引入中介者模式。

我们对比一下facade模式

facade模式是几个小对象组成一个大对象,如汽车这个对象里包含轮子、方向盘等对象,汽车就是轮子等对象的外观,我们将轮子封装到汽车里,并且将他们的方法提供到汽车对象里。

Facade模式是解藕系统外到系统内(单向)的对象关联关系;mediator模式是解藕系统内各个对象之间(双向)的关联关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值