一. 定义

在现实生活中,常出现多个对象之间存在复杂的交互关系,这种交互关系常常是"网状结构",要求每个对象都必须知道它需要交互的对象.如:每个人必须记住他所有朋友的电话,若朋友中有人的电话变了,他必须让其他所有朋友一起修改,即“牵一发而动全身"。若能把这种“网状结构”改为“星形结构”将大大降低它们之间的“耦合性”,这时需要找一个“中介者”,如上问题只要在网上建立一个每个朋友都可以访问的“通信录”即可解决

中介者模式(Mediator Pattern)

1) 用一个中介对象来封装一系列的对象交互,中介者使各对象无需显示地相互引用,从而使其耦合松散,可独立改变它们之间的交互;

2) 中介者模式又叫调停模式,属于行为模式,它是迪米特法则的典型应用;

3) 比如MVC模式,C(Controller) 是M(Model) 和 V(View) 的中介者,在前后端交互时起到中间人作用;

二. 特点

1. 优点

1) Mediator的出现减少了各个Colleague之间的藕合,使得可以独立地改变和复用各个Colleague和Mediator;

2) 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于扩展与维护;

2. 缺点

由于Mediator中包含所有的Colleague对象,所有控制都在Mediator的sendMessage函数中实现,使得中介者过于复杂。

三. 应用场景

1. 当对象间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时 (通信较为复杂);

2. 当想创建一个运行于多个类之间的对象,有不想生成新的子类时;

四. 模式的结构

1.中介者模式结构图

2.中介者模式角色及职责

   1) Mediator(抽象中介者): 定义了同事对象注册到中介者对象与转发同事对象信息的接口;

   2) ConcreteMediator(具体中介者): 实现抽象方法,使用一个HashMap对具体同事类进行管理,并接受同事对象消息完成相应任务;

   3) Colleague(抽象同事类): 保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

   4) ConcreteColleague(具体同事类): 只知自己的行为,而不知其他同事行为,当需与其他同事交互时,由中介者对象负责后续交互;

五. 模式的实现

0. 项目需求-智能家庭项目:

1)智能家庭包括各种设备, 闹钟、咖啡机、电视机、窗帘等

2)主人要看电视时: 各个设备可协同工作,自动完成看电视的准备工作,流程为:

闹钟响起->咖啡机开始做咖啡->窗帘自动落下 ->电视机播放 ->做好咖啡 -> 关闭电视-> 拉起窗帘

1.传统方案解决

闹钟响起-通知->咖啡机开始做咖啡-通知->窗帘自动落下-通知->电视机播放 -通知->做好咖啡 -通知->关闭电视 -通知->拉起窗帘

1)当各电器对象有多种状态改变时,相互之间的调用关系会比较复杂,各电器你中有我,我中有你,不利于松耦合;

2)各电器对象间所传递的消息(参数),容易混乱;

3)当系统增加一个新的电器对象时,或执行流程改变时,代码的可维护性、扩展性都不理想,考虑使用中介者模式;

2.中介者模式

0> 中介者模式-智能家庭的操作流程

1)创建ConcreteMediator 具体中介实现类对象;

2)根据电器类创建各个同事类对象(子类电器),如: Alarm、CoffeeMachine、TV...

3)在创建同事类对象的时候,就直接通过构造器,加入到ColleagueMap;

4)同事类对象,可调用sendMessage(),最终会去调用ConcreteMediator的 getMessage();

5)getMessage 会根据接收到的同事对象发出的消息来协调,调用其他的同事对象;

6)可以看到getMessage()是核心方法,完成相应的任务;

1> 实例结构图

2> 相关代码实现

object MediatorClient {    @JvmStatic
    fun main(args: Array<String>) {        //创建一个中介者对象
        val mediator=ConcreteMediator()
        //创建Alarm 并加入到ConcreteMediator 对象的 HashMap
        val alarm =Alarm(mediator)
        CoffeeMachine(mediator)
        Curtains(mediator)
        TV(mediator)
        //让闹钟发出消息
        alarm.sendAlarm()
    }
}
//抽象中介者
abstract class Mediator {    //将一个中介者对象加入到一个集合中
    abstract fun register(colleague: Colleague)    //接收消息,具体的同事对象发出
    abstract fun getMessage(colleagueName: String, stateChange: Int)
}
//具体的中介者类
class ConcreteMediator : Mediator() {    //集合, 放入所有的同事对象
    private var colleagueMap: HashMap<String, Colleague> = HashMap()
    //将各个具体同事类注册到HashMap中 进行管理
    override fun register(colleague: Colleague) {        colleagueMap[colleague.name] = colleague
    }
    /**
     * 具体中介者的核心方法
     * 1.根据得到的消息,完成对应任务
     * 2.中介者在这个方法中,协调各个具体的同事对象,完成任务;
     */
    override fun getMessage(colleagueName: String, stateChange: Int) {        when (colleagueMap[colleagueName]) {            is Alarm -> {                (colleagueMap["CoffeeMachine"] as CoffeeMachine?)?.startCoffee()
            }
            is CoffeeMachine -> { //咖啡通知
                if (stateChange == 0) {                    (colleagueMap["Curtains"] as Curtains?)?.downCurtains()
                } else {                    (colleagueMap["TV"] as TV?)?.stopTV()
                    (colleagueMap["Curtains"] as Curtains?)?.upCurtains()
                }
            }
            is Curtains -> { //如果是窗帘发出的消息 在这里处理
                (colleagueMap["TV"] as TV?)?.startTV()
            }
            is TV -> { //如果是TV 发出的消息 在这里处理
                (colleagueMap["CoffeeMachine"] as CoffeeMachine?)?.finishCoffee()
            }
        }
    }
}
//抽象同事类
abstract class Colleague (var mMediator:Mediator){    var name: String = this.javaClass.simpleName
    fun getMediator():Mediator{        return mMediator
    }
    abstract fun sendMessage(stateChange:Int =0)
}
//具体同事类 - 闹铃
class Alarm (mMediator:Mediator):Colleague(mMediator){    init {        //在创建Alarm同事对象时,将自己放入到ConcreteMediator 对象中[集合]
        mMediator.register(this)
    }    fun sendAlarm() {        sendMessage()
    }
    override fun sendMessage(stateChange: Int) {        //调用中介者对象的getMessage()
        getMediator().getMessage(name,stateChange)
    }
}
//具体同事类 - 咖啡机
class CoffeeMachine (mMediator:Mediator):Colleague(mMediator){    init {        mMediator.register(this)
    }    fun startCoffee() {        println("at this point to start making Coffee")
        sendMessage(0)
    }    fun finishCoffee(){        println("After 5 minutes!")
        println("Coffee is Ok!")
        sendMessage(1)
    }
    override fun sendMessage(stateChange: Int) {        getMediator().getMessage(name,stateChange)
    }
}
//具体同事类 - 窗帘
class Curtains (mMediator:Mediator):Colleague(mMediator){    init {        //在创建Alarm同事对象时,将自己放入到ConcreteMediator 对象中[集合]
        mMediator.register(this)
    }    fun downCurtains() {        println("at this point to draw down the curtain")
        sendMessage()
    }    fun upCurtains() {        println("at this point to hold the curtain")
    }
    override fun sendMessage(stateChange: Int) {        //调用中介者对象的getMessage()
        getMediator().getMessage(name,stateChange)
    }
}
//具体同事类 - 电视
class TV(mMediator: Mediator) : Colleague(mMediator) {    init {        mMediator.register(this)
    }    fun startTV() {        println("at this point to start TV")
        sendMessage()
    }    fun stopTV() {        println("at this point to stop TV")
    }    override fun sendMessage(stateChange: Int) {        getMediator().getMessage(name, stateChange)
    }
}

程序运行结果

at this point to start making Coffee
at this point to draw down the curtain
at this point to start TV
After 5 minutes!
Coffee is Ok!
at this point to stop TV
at this point to hold the curtain

六.中介模式与外观模式的区别

1.外观模式是结构型模式,中介者模式是行为型模式;

2.外观模式是对子系统提供统一的接口,中介者模式是用一个中介对象来封装一系列同事对象的交互行为;

3.外观模式协议是单向,中介者模式协议是双向。

4.外观模式所有的请求处理都委托给子系统完成,而中介者模式则由被具体中介者协调同事类和具体中介者本身共同完成业务。

7.7 中介者模式(Mediator Pattern)相关推荐

  1. 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)

    [索引页] [源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:webabcd 介绍 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互 ...

  2. java中介者模式例子_Java中介者模式(Mediator Pattern)

    本篇文章帮大家学习java中介者模式(Mediator Pattern),包含了Java中介者模式(Mediator Pattern)使用方法.操作技巧.实例演示和注意事项,有一定的学习价值,大家可以 ...

  3. PHP设计模式之中介者模式(Mediator Pattern)了解下

    咱们先来看下中介者模式(Mediator Pattern)的定义,它就是,用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互, ...

  4. 设计模式-中介者模式(Mediator Pattern)

    设计模式-中介者模式(Mediator Pattern) 文章目录 设计模式-中介者模式(Mediator Pattern) 一.定义 二.概念解释 三.场景 四.实现 1.类图 2.代码实现 五.总 ...

  5. 【23种设计模式】中介者模式(Mediator Pattern) .Net Core实现

    文章目录 简介 伪代码演示 简单实现 使用MediatR实现中介者模式 来源 简介 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类 ...

  6. [设计模式] 17 中介者模式 Mediator Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 ...

  7. 设计模式之中介者模式---Mediator Pattern

    模式的定义 中介者模式定义如下: Define an object that encapsulates how a set of objects interact.Mediator promotes ...

  8. 设计模式之中介者模式(Mediator Pattern)

    中介者模式定义 Define an object that encapsulates how a set of objects interact. Mediator promotes loose co ...

  9. [设计模式]8. C++与中介者模式(mediator pattern)

    意图:用一个中介者对象封装一系列的对象交互.中介者使各对象不需要显式的相互引用,从而减小耦合. 原文:默默的EEer 地址:http://www.cnblogs.com/hebaichuanyeah/ ...

最新文章

  1. 开源监控解决方案Nagios+Cacti+PNP4Nagios+NConf+NDOUtils+Nagvis(六)ndoutils安装
  2. cnn 反向传播推导_深度学习中的参数梯度推导(三)下篇
  3. [导入]第 3 章 Enterprise Library 的设计
  4. openssl1.1.0 支持php,openssl升级到1.0.21以支持nginx http2 ssl
  5. 从英伟达 vs ATI的芯片大战看GPU前世今生
  6. 理解 XML Schema:XML Schema 初步 (I)
  7. 数据中心效率:40%的改进是通过最佳实践方案
  8. ssl自签名证书生成脚本
  9. Fiddler2汉化版使用说明
  10. AvalonDock使用(2)-简单布局设置
  11. [MOT学习笔记]JDE损失函数详解
  12. 根据子节点递归查询所有父节点
  13. 利用MEGA计算π值和Ka/Ks
  14. 如何查询我的连连跨境支付提现手续费费率?
  15. 步步为营Hibernate全攻略(二)剪不断理还乱之:一对多关联映射
  16. 案例学习-产品模块和快报模块
  17. SSH2远程连接例子
  18. 深入理解LightGBM
  19. 【算法】一文详解贪心法
  20. 【STM32Cube】基于H743的SPI配置

热门文章

  1. osg中使用MatrixTransform来实现模型的平移/旋转/缩放
  2. 了解和使用keystone(五)获取token
  3. Excel中数据对比
  4. 西安oracle总部考场,西安oracle数据库培训地址在哪
  5. CentOS_6.5 x86_64 制作U盘启动方法
  6. Oracle物化视图:创建最简单物化视图
  7. IT运维之安全操作维护手册
  8. Unity2D锁链效果实现(一)——HingeJoint2D组件的使用
  9. 解决出国旅游语言障碍,安利三款实用的英文翻译软件
  10. [法语] 讲法语的42个国家与地区