基本需求

  • 智能家庭包括各种设备,闹钟、咖啡机、电视机、窗帘等
  • 要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流程为:闹铃响起->咖啡机开始做咖啡->窗帘自动落下->电视机开始播放

传统方案

  • 各个类之间相互调用,依赖严重,消息传递不准确,调用结构混乱
  • 说明
    • 当各电器对象有多种状态改变时,相互之间的调用关系会比较复杂
    • 各个 电器对象彼此联系,你中有我,我中有你,不利于松耦合
    • 各个电器对象之间所传递的消息(参数),容易混乱
    • 当系统增加一个新的电器对象时,或者执行流程改变时,代码的可维护性、扩展性都不理想 考虑中介者模式

基本介绍

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

  • 中介者模式属于行为型模式,使代码易于维护

  • 比如MVC模式,C(Controller 控制器)是M(Model 模型)和V(View 视图)的中介者,在前后端交互时起到了中间人的作用

  • 比如租房子

    • 没有中介:有六个房东需要出租房屋,适合不一样的人租住。这六个房东之间有点联系。这时租客来租房,看了一号房东的房子不满意、但是一号房东觉得可以让他去看看其他五个朋友的房间。然后开始联系五个朋友。进行消息传递。一个如此,另外五个亦如此,如果二号房东房屋不出租或者出租出去了,情况发生了变化。他则需要通知其他五个朋友,告诉他们不用再给他介绍租客。这里就造成了中间一个人发生了变化,需要改动其他五个人
    • 有中介:那六个房东都把房屋交给中介处理。租客A看房间一不满意直接通过中介看房间二。当房间二被出租了。中介也只需要通知房东二号、然后他们签订合同。下次还有人看房间就不会再看房间二。这里一个出现了变化也就影响改变了一个。并不会影响其他另外五个房东
  • UML类图(原理)

    • 说明
      • Mediator 就是抽象中介者,定义了同事对象到中介者对象的接口
      • Colleague 是抽象同事类
      • ConcreteMediator 具体的中介者对象, 实现抽象方法, 他需要知道所有的具体的同事类,即以一个集合来管理HashMap,并接受某个同事对象消息,完成相应的任务
      • ConcreteColleague 具体的同事类,会有很多, 每个同事只知道自己的行为,而不了解其他同事类的行为(方法),但是他们都依赖中介者对象
  • UML类图(案例)

    • 说明
      • ConcreteMediator是中介者实现类
      • 在创建同事实现类的时候通过其构造方法将其注册到中介者中,通过sendMessage方法向中介者发送消息
      • ConcreteMediator的getMessage方法会接收到同事类的消息协调调用其他对象,是核心方法
  • 代码实现

    • public abstract class Mediator {
      
         // 中介者抽象类
      
         // 将同事类加入到中介者中,由中介者对所有同事类进行交互,同事类之间不进行交互
      // 将依赖由网状变成星状
      public abstract void register(String colleagueName, Colleague colleague); // 接收消息 由同事类发出
      public abstract void getMessage(String colleagueName, int stateChange); // 发送消息,发给同事类,本次案例中没有用到
      public abstract void sendMessage(); } // 中介者实现类
      public class ConcreteMediator extends Mediator { // 使用集合管理所有的中介者,如果key重复,则是最新注册的 ,可否弄成MapList的形式管理重复key
      private Map<String, Colleague> colleagueMap; // 名称的集合,方便我们自己获取对应的同事类,因为每次注册时 我们并不知道key,想获取value时不能获取,指定名称 后续使用简单
      private Map<String, String> nameMap; public ConcreteMediator() {
      this.colleagueMap = new HashMap<>();
      this.nameMap = new HashMap<>();
      } @Override
      public void register(String colleagueName, Colleague colleague) {
      colleagueMap.put(colleagueName, colleague);
      if (colleague instanceof Alarm) {
      // 自定义名称 方便我们下面使用
      nameMap.put("alarm", colleagueName);
      } else if (colleague instanceof CoffeeMachine) {
      nameMap.put("coffeeMachine", colleagueName);
      } else if (colleague instanceof Curtain) {
      nameMap.put("curtain", colleagueName);
      } else if (colleague instanceof TV) {
      nameMap.put("tv", colleagueName);
      }
      } @Override
      public void getMessage(String colleagueName, int stateChange) {
      // 根据得到消息,完成对应任务,中介者在这个方法,协调各个具体的同事对象,完成任务
      if (colleagueMap.get(colleagueName) instanceof Alarm) {
      // 处理闹钟的消息 可使用中介者的sendMessage方法进行处理
      if (stateChange == 0) {
      ((CoffeeMachine) colleagueMap.get(nameMap.get("coffeeMachine"))).startCoffee();
      ((TV) colleagueMap.get(nameMap.get("tv"))).startTv();
      } else if (stateChange == 1) {
      ((TV) colleagueMap.get(nameMap.get("tv"))).stopTv();
      }
      } else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
      // 处理咖啡机的消息
      if (stateChange == 0) {
      ((Curtain) colleagueMap.get(nameMap.get("curtain"))).upCurtains();
      }
      } else if (colleagueMap.get(colleagueName) instanceof Curtain) {
      // 处理窗帘的消息
      System.out.println();
      } else if (colleagueMap.get(colleagueName) instanceof TV) {
      // 处理电视机的消息
      System.out.println();
      }
      } @Override
      public void sendMessage() { }
      }
    • public abstract class Colleague {
      
         // 同事抽象类
      
         protected String name;
      
         private Mediator mediator;
      
         public Colleague(String name, Mediator mediator) {
      this.name = name;
      this.mediator = mediator;
      } public Mediator getMediator() {
      return this.mediator;
      } // 发送消息
      public abstract void sendMessage(int stateChange); } // 同事子类一 闹钟类
      public class Alarm extends Colleague { public Alarm(String name, Mediator mediator) {
      super(name, mediator);
      // 将自己在中介者中进行注册
      mediator.register(name, this);
      } @Override
      public void sendMessage(int stateChange) {
      // 获取中介者 调用中介者的getMessage方法 将消息传递给中介者 由中介者处理消息
      this.getMediator().getMessage(super.name, stateChange);
      } public void sendAlarm(int stateChange) {
      sendMessage(stateChange);
      }
      } // 同事子类二 咖啡机
      public class CoffeeMachine extends Colleague { public CoffeeMachine(String name, Mediator mediator) {
      super(name, mediator);
      mediator.register(name, this);
      } @Override
      public void sendMessage(int stateChange) {
      this.getMediator().getMessage(super.name, stateChange);
      } public void startCoffee() {
      System.out.println("It's time to startcoffee!");
      } public void finishCoffee() {
      System.out.println("After 5 minutes!");
      System.out.println("Coffee is ok!");
      sendMessage(0);
      }
      } // 同事子类三 窗帘
      public class Curtain extends Colleague { public Curtain(String name, Mediator mediator) {
      super(name, mediator);
      mediator.register(name, this);
      } @Override
      public void sendMessage(int stateChange) {
      this.getMediator().getMessage(super.name, stateChange);
      } public void upCurtains() {
      System.out.println("I am holding Up Curtains!");
      }
      } // 同事子类四 电视机
      public class TV extends Colleague { public TV(String name, Mediator mediator) {
      super(name, mediator);
      mediator.register(name, this);
      } @Override
      public void sendMessage(int stateChange) {
      this.getMediator().getMessage(super.name, stateChange);
      } public void startTv() {
      System.out.println("It's time to StartTv!");
      } public void stopTv() {
      System.out.println("Stop Tv!");
      }
      }

注意事项

  • 多个类相互耦合,会形成网状结构, 使用中介者模式将网状结构分离为星型结构,进行解耦
  • 如果增加一个同事类,直接增加即可,降低了类的复杂度,将一对多转化成了一对一
  • 减少类间依赖,降低了耦合,符合迪米特原则
  • 中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响
  • 中介者 承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响

18.java设计模式之中介者模式的更多相关文章

  1. 折腾Java设计模式之中介者模式

    博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...

  2. 从中国加入WTO来看Java设计模式:中介者模式

    目录 应用场景 中介者模式 定义 意图 主要解决问题 何时使用 优缺点 世界贸易组织WTO 应用场景 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象 想通过一个 ...

  3. Java 设计模式之中介者模式

    本文继续23种设计模式系列之中介者模式.   定义 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互.   角色 抽象中介者: ...

  4. java设计模式之中介者模式

    中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...

  5. Java 设计模式 之 中介者模式(Mediator)

    中介者的功能非常简单,就是封装对象之间的交互. 如果一个对象的操作会引起其他相关对象的变化,或者是某个操作需要引起其他对象的后续或连带操作,而这个对象又不希望自己来处理这些关系,那么久可以找中介者,把 ...

  6. Java设计模式之《代理模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6525527.html 代理模式算是我接触较早的模式,代理就是中介,中间人.法律上也有代理, ...

  7. Java设计模式之工厂方法模式(转) 实现是抽象工厂?

    Java设计模式之工厂方法模式 责任编辑:覃里作者:Java研究组织   2009-02-25   来源:IT168网站   文本Tag: 设计模式 Java [IT168 技术文章]         ...

  8. Java设计模式 - - 单例模式 装饰者模式

    Java设计模式 单例模式 装饰者模式 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 静态代理模式:https://www.cnblogs.com/StanleyBlogs/p/1 ...

  9. 重学 Java 设计模式:实战桥接模式(多支付渠道「微信、支付宝」与多支付模式「刷脸、指纹」场景)

    作者:小傅哥 博客:https://bugstack.cn - 编写系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 为什么你的代码那么多ifelse 同类的业务.同样的功能, ...

随机推荐

  1. Python3中zipfile模块文件名乱码问题

    inux下zip文件乱码已经是一个常见问题了,再加上python想不遇到乱码问题都难. 在zipfile.ZipFile中获得的filename有中日文则很大可能是乱码,这是因为 在zip标准中,对文 ...

  2. PHP语言基础知识

    目录 前言 第一章 PHP语言学习介绍 1.1 PHP部署安装环境 1.2 PHP代码工具选择 第二章 PHP代码基本语法 2.1 PHP函数知识介绍 2.2 PHP常量变量介绍 2.2.1 PHP变 ...

  3. sessionStorage 退出登录删除sessionStorage储存

    1 登录后在sessionStorage中添加token的值,退出后清空 登录后在sessionStorage中添加token的值,退出后清空 localStorage 和 sessionStorag ...

  4. java web简单的增删改查

    1.主要的文件,运行结果,运行界面,数据库创建的表等图片. 所要创建的文件和要导入的包: 主页面: 显示界面: 数据库的信息: 删除.查找.修改就不一 一列出来,自己可以运行看看.哈哈 2.接下来我将 ...

  5. JVM虚拟机(一):类加载机制

    类加载的时机   类加载的生命周期为: 加载.验证.准备.解析.初始化.使用.卸载七个阶段,其中验证.准备.解析三个阶段统称为连接.其中加载与连接时交叉执行的. 类必须初始化的六种情况 遇到new.g ...

  6. 图解Janusgraph系列-并发安全:锁机制(本地锁+分布式锁)分析

    图解Janusgraph系列-并发安全:锁机制(本地锁+分布式锁)分析 大家好,我是洋仔,JanusGraph图解系列文章,实时更新~ 图数据库文章总目录: 整理所有图相关文章,请移步(超链):图数据 ...

  7. BUUCTF | [网鼎杯 2020 朱雀组]phpweb

    一道比较简单的题,不过对PHP还是不够熟悉 知识点 1.PHP date函数 PHP date() 函数用于对日期或时间进行格式化. 语法 date(format,timestamp) 参数 描述 f ...

  8. ID3很不错的讲解(matlab程序实现)

    1)决策树之ID3 决策树算法是分类算法的一种,基础是ID3算法,C4.5.C5.0都是对ID3的改进.ID3算法的基本思想是,选择信息增益最大的属性作为当前的分类属性. 看Tom M. Mitche ...

  9. 【命令】ln命令

    这是linux中一个非常重要命令,请大家一定要熟悉.它的功能是为某一个文件或目录在另外一个位置建立一个同步的链接,默认是链接是硬链接,常用参数是 "-s"  . 对于ln命令,这里 ...

  10. 【JAVA并发第二篇】Java线程的创建与运行,线程状态与常用方法

    1.线程的创建与运行 (1).继承或直接使用Thread类 继承Thread类创建线程: /** * 主类 */ public class ThreadTest { public static voi ...