3-5设计模式之中介者模式(Mediator)

3.5.1 模式意图:

在系统中,会存在多对象间交叉连接的情况,为了减少对象间的直接引用,满足迪米特法则,可以使用一个中介层来代替原有多对象间的直接相互引用,使原来的多个对象所关联的其他对象保持最少。这也就是今天介绍的中介者模式,这种模式很类似于生活中的配送服务,货物从生产商发货送并非直接送到收货人的手中,而是先把货物发送到中转站,再由中转站根据货物的信息发送到收件人的地址。避免了生产商和收件人的直接联系。

3.5.2 模式概念:

它属于行为型模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要直接的相互引用,从而使其耦合松散,可以独立地改变他们之间的交互。

3.5.3 模式元素:

  • 中介抽象(Mediator)
  • 中介细节(ConcreteMediator)
  • 对象抽象(Group)
  • 对象细节(ConcreateGroup0、ConcreateGroup1)

3.5.4 代码示例:

A.中介者

    public abstract class Mediator
    {
        public abstract void SendMessage(Group theColleague,string Message);
    }

    public class ConcreteMediator : Mediator
    {
        ConcreateGroup0 group0 = null;
        ConcreateGroup1 group1 = null;

        public void SetColleageu1(ConcreateGroup0 theColleague)
        {
            group0 = theColleague;
        }

        public void SetColleageu2(ConcreateGroup1 theColleague)
        {
            group1 = theColleague;
        }

        public override void SendMessage(Group theColleague, string Message)
        {
            if (group0 == theColleague)
                group1.ReceiveMessage(Message);

            if (group1 == theColleague)
                group0.ReceiveMessage(Message);
        }
    }

B.交互对象

    public abstract class Group
    {
        protected Mediator mediator = null;
        public Group( Mediator mediator)
        {
            this.mediator = mediator;
        }
        public abstract void ReceiveMessage(string Message);

    }

    public class ConcreateGroup0 : Group
    {
        public ConcreateGroup0( Mediator theMediator) : base(theMediator){}
        public void Action()
        {
            mediator.SendMessage(this,nameof(ConcreateGroup0)+"发出消息");
        }

        public override void ReceiveMessage(string Message)
        {
            Debug.Log(nameof(ConcreateGroup0) + "收到:" + Message);
        }
    }   

    public class ConcreateGroup1 : Group
    {
        public ConcreateGroup1( Mediator theMediator) : base(theMediator){}

        public void Action()
        {
            mediator.SendMessage(this, nameof(ConcreateGroup1) + "发出消息");
        }

        public override void ReceiveMessage(string Message)
        {
            Debug.Log(nameof(ConcreateGroup1) +"收到:"+ Message);
        }
    }   

示例代码调用

    void Start()
    {
        ConcreteMediator mediator = new ConcreteMediator();

        ConcreateGroup0 group0 = new ConcreateGroup0(mediator);
        ConcreateGroup1 group1 = new ConcreateGroup1(mediator);

        mediator.SetColleageu1(group0);
        mediator.SetColleageu2(group1);

        group0.Action();
        group1.Action();
    }

打印结果

3.5.5 写法对比:

3.5.6 模式分析:

中介者模式降低了类的复杂度,将一对多转化成了一对一的形式,使各个类之间的解耦降低,符合迪米特法则

中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了多对多交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是否合理。在需求不明确或者变更频繁时尽量少用中介者模式。因为中介者会庞大,变得复杂难以维护。违背了松耦合及后期便于维护的初衷。

3.5.7 应用场景:

  • 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

3.5.8 小结:

通过添加额外的中介者,将多对象间的直接引用转换成间接引用形式。但中介者模式并不是减少对象间耦合度的万金油,在使用中介者模式时,还是要进行详细的需求分析,抽象出需求中的深层概念,才能更好的使用设计模式。


更多设计模式详见:设计模式全家桶

发表评论