zoukankan      html  css  js  c++  java
  • 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设计模式之目录 

  • 相关阅读:
    [MFC] MFC 用mciSendString加载WAV资源文件
    [JS] HTML QQ分享界面js代码
    [MFC] MFC 打开HTML资源(用ID版,也可加载到自己的web控件上)
    [ACM_暴力][ACM_几何] ZOJ 1426 Counting Rectangles (水平竖直线段组成的矩形个数,暴力)
    [ACM_动态规划] ZOJ 1425 Crossed Matchings(交叉最大匹配 动态规划)
    easyui combobox可编辑的情况下,只能首字母开始过滤的问题选项
    easyui-combobox绑定回车事件注意事项
    easyui-combobox绑定回车事件相关
    jquery-qrcode 生成和读取二维码
    zxing生成二维码和读取二维码
  • 原文地址:https://www.cnblogs.com/xcsn/p/7499161.html
Copyright © 2011-2022 走看看