Mediator(中介者)

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值