Head First设计模式之中介者模式

一、定义

又称为调停者模式,定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互。

二、结构

组成:

  ● 抽象中介者(Mediator)角色:定义统一的接口用于各同事角色之间的通信,其中主要方法是一个(或多个)事件方法。

  ● 具体中介者(ConcreteMediator)角色:实现了抽象中介者所声明的事件方法。具体中介者知晓所有的具体同事类,并负责具体的协调各同事对象的交互关系。

  ● 抽象同事类(Colleague)角色:定义出中介者到同事角色的接口。同事角色只知道中介者而不知道其余的同事角色。与其他的同事角色通信的时候,一定要通过中介者角色协作。

  ● 具体同事类(ConcreteColleague)角色:所有的具体同事类均从抽象同事类继承而来。实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者会负责与其他的同事交互。

代码结构

 //抽象中介者类
    public interface IMediator
    {
        /**
         * 同事对象在自身改变的时候来通知中介者的方法
         * 让中介者去负责相应的与其他同事对象的交互
         */
        void Changed(Colleague c);
    }

    //抽象同事类
    public abstract class Colleague
    {
        //持有一个中介者对象
        private IMediator _mediator;
        /**
         * 构造函数
         */
        public Colleague(IMediator mediator)
        {
            this._mediator = mediator;
        }
        /**
         * 获取当前同事类对应的中介者对象
         */
        public IMediator GetMediator()
        {
            return _mediator;
        }
    }

    //具体中介者类
    public class ConcreteMediator : IMediator
    {
        //持有并维护同事A
        private ConcreteColleagueA _colleagueA;
        //持有并维护同事B
        private ConcreteColleagueB _colleagueB;

        public void SetColleagueA(ConcreteColleagueA colleagueA)
        {
            this._colleagueA = colleagueA;
        }

        public void SetColleagueB(ConcreteColleagueB colleagueB)
        {
            this._colleagueB = colleagueB;
        }

        public void Changed(Colleague c)
        {
            /**
             * 某一个同事类发生了变化,通常需要与其他同事交互
             * 具体协调相应的同事对象来实现协作行为
             */
        }
    }

    //具体同事类
    public class ConcreteColleagueA : Colleague
    {

        public ConcreteColleagueA(IMediator mediator) : base(mediator)
        {
        }
        /**
         * 示意方法,执行某些操作
         */
        public void Operation()
        {
            //在需要跟其他同事通信的时候,通知中介者对象
            GetMediator().Changed(this);
        }
    }
    public class ConcreteColleagueB : Colleague
    {

        public ConcreteColleagueB(IMediator mediator) : base(mediator)
        { 
        }
        /**
         * 示意方法,执行某些操作
         */
        public void Operation()
        {
            //在需要跟其他同事通信的时候,通知中介者对象
            GetMediator().Changed(this);
        }
    }

 

三、适用场景

1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。

2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

应用实例

1、中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。

2、机场调度系统。

3、MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

四、优缺点

  优点: 1、降低了类的复杂度,将一对多转化成了一对一。 2、各个类之间的解耦。 3、符合迪米特原则。

  缺点:中介者会庞大,变得复杂难以维护。

五、实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatterns.Mediator
{
    class Program
    {
        static void Main(string[] args)
        {
            MessageMediator mediator = new MessageMediator();

            ConcreteColleagueA a = new ConcreteColleagueA(mediator, "A");
            ConcreteColleagueB b = new ConcreteColleagueB(mediator, "B");
            ConcreteColleagueC c = new ConcreteColleagueC(mediator, "C");

            mediator.SetColleagueA(a);
            mediator.SetColleagueB(b);
            mediator.SetColleagueC(c);

            mediator.Chat(a, "中午吃啥饭?");
            Console.WriteLine("====");

            mediator.Chat(b, "我想吃刀削面");
            Console.WriteLine("====");

            mediator.Chat(c, "我也想吃刀削面");
            Console.WriteLine("====");
            
            mediator.Chat(a, "行,那中午一起去吃刀削面吧");
        }
    }

    //抽象中介者类
    public interface IMediator
    { 
        void Chat(Colleague c, string message);
    }

    //抽象同事类
    public abstract class Colleague
    {
        private string name;
        //持有一个中介者对象
        private IMediator _mediator;
        
        public Colleague(IMediator mediator, string name)
        {
            this._mediator = mediator;
            this.name = name;
        }
        /**
         * 获取当前同事类对应的中介者对象
         */
        public IMediator GetMediator()
        {
            return _mediator;
        }

        /**
         * 获取昵称
         */
        public string getName()
        {
            return name;
        }

        /**
         * 接收消息
         */
        public abstract void receive(string message);

        /**
         * 发送消息
         */
        public abstract void send(string message);
    }

    //具体中介者类
    public class MessageMediator : IMediator
    {
        //持有并维护同事A
        private ConcreteColleagueA _colleagueA;
        //持有并维护同事B
        private ConcreteColleagueB _colleagueB;

        private ConcreteColleagueC _colleagueC;

        public void SetColleagueA(ConcreteColleagueA colleagueA)
        {
            this._colleagueA = colleagueA;
        }

        public void SetColleagueB(ConcreteColleagueB colleagueB)
        {
            this._colleagueB = colleagueB;
        }
        public void SetColleagueC(ConcreteColleagueC colleagueC)
        {
            this._colleagueC = colleagueC;
        }

        public void Chat(Colleague c, string message)
        {
            if (_colleagueA != null)
            {
                _colleagueA.send(message);
                _colleagueB.receive(message);
                _colleagueC.receive(message);
            }
            else if (_colleagueB != null) {
                _colleagueB.send(message);
                _colleagueA.receive(message);
                _colleagueC.receive(message);
            } else if (_colleagueC != null) {
                _colleagueC.send(message);
                _colleagueA.receive(message);
                _colleagueB.receive(message);
            }
        }
    }

    //具体同事类
    public class ConcreteColleagueA : Colleague
    {

        public ConcreteColleagueA(IMediator mediator, string name) : base(mediator, name)
        {
        }
        /**
         * 示意方法,执行某些操作
         */
        public void Operation(string message)
        {
            //在需要跟其他同事通信的时候,通知中介者对象
            GetMediator().Chat(this, message);
        }

        public override void receive(String message)
        {
            Console.WriteLine("【A】收到消息:【" + message + "");
        }

        public override void send(String message)
        {
            Console.WriteLine("【A】发出消息:【" + message + "");
        }
    }
    public class ConcreteColleagueB : Colleague
    {

        public ConcreteColleagueB(IMediator mediator, string name) : base(mediator, name)
        {
        }
        /**
         * 示意方法,执行某些操作
         */
        public void Operation(string message)
        {
            //在需要跟其他同事通信的时候,通知中介者对象
            GetMediator().Chat(this, message);
        }

        public override void receive(String message)
        {
            Console.WriteLine("【B】收到消息:【" + message + "");
        }

        public override void send(String message)
        {
            Console.WriteLine("【B】发出消息:【" + message + "");
        }
    }


    public class ConcreteColleagueC : Colleague
    {

        public ConcreteColleagueC(IMediator mediator, string name) : base(mediator, name)
        {
        }
        /**
         * 示意方法,执行某些操作
         */
        public void Operation(string message)
        {
            //在需要跟其他同事通信的时候,通知中介者对象
            GetMediator().Chat(this, message);
        }

        public override void receive(String message)
        {
            Console.WriteLine("【C】收到消息:【" + message + "");
        }

        public override void send(String message)
        {
            Console.WriteLine("【C】发出消息:【" + message + "");
        }
    }
}

结果

【A】发出消息:【中午吃啥饭?】
【B】收到消息:【中午吃啥饭?】
【C】收到消息:【中午吃啥饭?】
====
【A】发出消息:【我想吃刀削面】
【B】收到消息:【我想吃刀削面】
【C】收到消息:【我想吃刀削面】
====
【A】发出消息:【我也想吃刀削面】
【B】收到消息:【我也想吃刀削面】
【C】收到消息:【我也想吃刀削面】
====
【A】发出消息:【行,那中午一起去吃刀削面吧】
【B】收到消息:【行,那中午一起去吃刀削面吧】
【C】收到消息:【行,那中午一起去吃刀削面吧】

 

参考:

http://www.cnblogs.com/JsonShare/p/7263876.html

http://www.runoob.com/design-pattern/mediator-pattern.html

 

 


欢迎阅读本系列文章:Head First设计模式之目录 

 

posted @ 2017-09-09 20:03  心存善念  阅读(520)  评论(0编辑  收藏  举报