用一个中介对象来封装一系列对象的交互。中介者使得各对象不需要显式相互引用,从而使其松散耦合,而且可以独立地改变它们之间的交互。
Mediator模式解决了一个问题,多个类相互引用相互,相互影响,这时候类的关系模型是复杂的,一个类对象的变化会导致其他类对象的变化,这种场景有点连锁反应的意思。下面有一段代码
class CutMenuItem
{
TextArea textArea;
ClipBorad clipBorad;
ToolBarButton toolBarButton;
public void Click()
{
string text = textArea.SelectedText;
textArea.RemoveSelectionText();
clipBorad.SetData(text);
toolBarButton.EnabledPasteButton();
}
}
class TextArea
{
ClipBorad clipBoard;
ToolBarButton toolBarButton;
CutMenuItem cutMenuItem;
internal void RemoveSelectionText()
{
}
}
class ClipBorad
{
ToolBarButton toolBarButton;
CutMenuItem cutMenuItem;
TextArea textArea;
internal void SetData(string text)
{
}
}
class ToolBarButton
{
ClipBorad clipBorad;
CutMenuItem cutMenuItem;
TextArea textArea;
internal void EnabledPasteButton()
{
}
}
上面有四个类:菜单、文本框、按钮、剪贴板,每个类里面都包含其他三个类的引用。当每个类的某个方法被调用时,会连锁的引起其他三个类的对象的方法的调用。如果我们按照这种方式来写的话,如果类比较多,我们会陷入一种混乱状态。我们需要一种设计模式,将他们进行解藕。因此我们使用Mediator设计模式
abstract class Mediator
{
public abstract void Notify();
public virtual void AddElement(Element element)
{
list.Add(element);
}
List<Element> list = new List<Element>();
}
abstract class Element
{
Mediator mediator;
public Element(Mediator mediator)
{
this.mediator = mediator;
this.mediator.AddElement(this);
}
public virtual void OnChange()
{
}
}
class TextArea : Element
{
public TextArea(Mediator mediator) : base(mediator)
{
}
public void Process()
{
OnChange();
}
}
class CutMenuItem : Element
{
public CutMenuItem(Mediator mediator) : base(mediator)
{
}
public void Click()
{
OnChange();
}
}
class ClipBoard : Element
{
public ClipBoard(Mediator mediator) : base(mediator)
{
}
public void Invoke()
{
OnChange();
}
}
class ToolBarButton : Element
{
public ToolBarButton(Mediator mediator) : base(mediator)
{
}
public void Click()
{
OnChange();
}
}
class ConcreteMediator : Mediator
{
public override void Notify()
{
}
}
在代码里面我们抽象了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模式是解藕系统内各个对象之间(双向)的关联关系
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/firewolffeng/archive/2008/09/23/2970037.aspx