zoukankan      html  css  js  c++  java
  • 深入浅出设计模式——中介者模式(Mediator Pattern)

    模式动机

    在用户与用户直接聊天的设计方案中,用户对象之间存在很强的关联性,将导致系统出现如下问题:
     系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他所有对象,并进行适当处理。
     对象可重用性差:由于一个对象和其他对象具有很强的关联,若没有其他对象的支持,一个对象很难被另一个系统或模块重用,这些对象表现出来更像一个不可分割的整体,职责较为混乱。
     系统扩展性低:增加一个新的对象需要在原有相关对象上增加引用,增加新的引用关系也需要调整原有对象,系统耦合度很高,对象操作很不灵活,扩展性差。
    在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责。
    对于一个模块,可能由很多对象构成,而且这些对象之间可能存在相互的引用,为了减少对象两两之间复杂的引用关系,使之成为一个松耦合的系统,我们需要使用中介者模式,这就是中介者模式的模式动机。

    模式定义
    中介者模式(Mediator Pattern)定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
    Mediator Pattern: Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
    Frequency of use: medium low
    UML图

    模式结构
    中介者模式包含如下角色:
    Mediator: 抽象中介者
    ConcreteMediator: 具体中介者
    Colleague: 抽象同事类
    ConcreteColleague: 具体同事类

    模式分析
    中介者模式可以使对象之间的关系数量急剧减少:
      

    模式分析
    中介者承担两方面的职责:
     中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,通过中介者即可。该中转作用属于中介者在结构上的支持。
     协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。
    中介者模式就是迪米特法则的一个典型应用。

    模式实例与解析
    世界需要和平—中介者模式示例

    体系结构

    Mediator: 抽象中介者 UnitedNations.cs

    namespace MediatorPattern
    {
        //联合国机构 相当于Mediator类
        abstract class UnitedNations
        {
            public abstract void Declare(string message, Country colleague);
        }
    }

    ConcreteMediator: 具体中介者 UnitedNationsSecurityCouncil.cs

    namespace MediatorPattern
    {
        class UnitedNationsSecurityCouncil : UnitedNations
        {
            private USA colleaguel;
            private Iraq colleague2;
            //联合国安理会会了解所有的国家,所以拥有美国和伊拉克的对象属性
            public USA Colleague1
            {
                set { colleaguel = value; }
            }
            public Iraq Colleague2
            {
                set { colleague2 = value; }
            }
    
            public override void Declare(string message, Country colleague)
            {
                if (colleague == colleaguel)
                {
                    colleague2.GetMessage(message);
                }
                else
                {
                    colleaguel.GetMessage(message);
                }
            }
        }
    }

    Colleague: 抽象同事类 Country.cs

    namespace MediatorPattern
    {
        //国家 相当于Colleague类
        abstract class Country
        {
            protected UnitedNations mediator;
            public Country(UnitedNations mediator)
            {
                this.mediator = mediator;
            }
        }
    }

    ConcreteColleague: 具体同事类 USA.cs

    using System;
    
    namespace MediatorPattern
    {
        //美国类 相当于ConcreteColleaguel类
        class USA : Country
        {
            public USA(UnitedNations mediator)
                : base(mediator)
            {
            }
            public void Declare(string message)
            {
                mediator.Declare(message, this);
            }
            //获得消息
            public void GetMessage(string message)
            {
                Console.WriteLine("美国获得对方信息:" + message);
            }
        }
    }

    Iraq.cs

    using System;
    
    namespace MediatorPattern
    {
        //伊拉克类 相当于ConcreteColleague2类
        class Iraq : Country
        {
            public Iraq(UnitedNations mediator)
                : base(mediator)
            {
            }
            public void Declare(string message)
            {
                mediator.Declare(message, this);
            }
            //获得消息
            public void GetMessage(string message)
            {
                Console.WriteLine("伊拉克获得对方信息:" + message);
            }
        }
    }

    Client:客户类

    using System;
    
    namespace MediatorPattern
    {
        class Program
        {
            static void Main(string[] args)
            {
                UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();
                USA c1 = new USA(UNSC);
                Iraq c2 = new Iraq(UNSC);
    
                UNSC.Colleague1 = c1;
                UNSC.Colleague2 = c2;
                c1.Declare("不准研制核武器,否则要发动战争!");
                c2.Declare("我们没有核武器,也不怕侵略");
                Console.Read();
            }
        }
    }

    模式优缺点
    中介者模式的优点
     简化了对象之间的交互。
     将各同事解耦。
     减少子类生成。
     可以简化各同事类的设计和实现。
    中介者模式的缺点
     在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。

    模式适用环境
    在以下情况下可以使用中介者模式:
     系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。
     一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
     想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的中介者类。

    【声明与感谢】
    本文,站在许多巨人的肩膀上,借鉴和引用了许多他人拥有版权的作品或著述,在此,对前人们的贡献致谢。并同时公布引用的内容、原作者或来源(一些来源于互联网的内容本人无法追述本源,深表遗憾)。

    【参考文献】
    《设计模式—可复用面向对象软件的基础》作者: [美] Erich Gamma / Richard Helm / Ralph Johnson / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 / 刘建中 等 机械工业出版社
    《重构—改善既有代码的设计》作者: Martin Fowler译者:候捷 中国电力出版社
    《敏捷软件开发—原则、模式与实践》作者: Robert C. Martin 清华大学出版社
    《程序员修炼之道—从小工到专家》作者: Andrew Hunt / David Thomas 电子工业出版社
    《Head First 设计模式》作者: 弗里曼 译者: O'Reilly Taiwan公司 中国电力出版社
    《设计模式之禅》 作者: 秦小波 机械工业出版社
    MSDN WebCast 《C#面向对象设计模式纵横谈》 讲师:李建忠
    刘伟. 设计模式. 北京:清华大学出版社, 2011.
    刘伟. 设计模式实训教程. 北京:清华大学出版社, 2012.
    《大话设计模式》 作者: 程杰 清华大学出版社
    《C#图解教程》作者: 索利斯 译者: 苏林 / 朱晔 人民邮电出版社
    《你必须知道的.NET》作者: 王涛
    《项目中的.NET》作者: 李天平 电子工业出版社
    《Microsoft .NET企业级应用架构设计》作者: (美)埃斯波西托等编著 译者: 陈黎夫
    http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns
    http://www.cnblogs.com/zhenyulu 博客作者:吕震宇
    http://www.cnblogs.com/terrylee 博客作者:李会军
    http://www.cnblogs.com/anlyren/ 博客作者:anlyren
    http://www.cnblogs.com/idior 博客作者:idior
    http://www.cnblogs.com/allenlooplee 博客作者:Allen lee
    http://blog.csdn.net/ai92 博客作者:ai92
    http://www.cnblogs.com/umlonline/ 博客作者:张传波
    http://www.cnblogs.com/lovecherry/ 博客作者:LoveCherry

  • 相关阅读:
    剔除数组中重复对象
    2018湖南省高中数学联赛(A)试题
    向量与三角
    阿波罗尼斯圆
    2019高考理科数学(天津卷)
    转载Android常见错误(http://www.cnblogs.com/oklanyan/archive/2011/10/12/2208378.html)
    TCP/IP网络层谜云
    bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化方法(转载:http://tonyyu.iteye.com/blog/713256)
    ArcGIS for Android 离线数据编辑原理
    Android环境搭建(XP/Win7)转载http://www.cnblogs.com/oklanyan/archive/2011/10/14/2207339.html
  • 原文地址:https://www.cnblogs.com/Bobby0322/p/4195683.html
Copyright © 2011-2022 走看看