0.参考资料



1.概述

  • 用一个中介对象来封装(封装变化)一系列的对象交互。中 介者使各对象不需要显式的相互弓|用(编译时依赖 —> 运行时 依赖) ,从而使其耦合松散(管理变化) , 而且可以独立地 改变它们之间的交互。 —《设计模式》GoF

1.1动机

  1. 1. 在软件构建过程中,经常会出现多个对象互相关联交互的情况,

对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更 改,这种直接的引用关系将面临不断的变化。

  1. 1. 在这种情况下,我们可使用一一个“中介对象”来管理对象间的关

联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地 抵御变化。

1.2结构

  1. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1630232335283-4c60bf4a-3d98-469f-b064-8f8d55d2609e.png#clientId=u62794ef2-ec1d-4&from=paste&height=164&id=u595a249d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=328&originWidth=1170&originalType=binary&ratio=1&size=72593&status=done&style=none&taskId=ua5ac6e49-3fbb-45a6-91c8-c97fd2c2263&width=585)
  2. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1630232652559-c950aa2d-5cdc-4740-bb2a-a27e99852b30.png#clientId=u62794ef2-ec1d-4&from=paste&id=u46bfd84c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=386&originWidth=714&originalType=binary&ratio=1&size=29074&status=done&style=none&taskId=u9a43f473-8ae3-40aa-a07f-2123dbafba4)
  3. - 角色 与职责分析
  4. - Mediator 就是抽象中介者,定义了同事对象到中介者对象的接口
  5. - ConcreteMediator 具体的中介者对象, 实现抽象方法, 他需要知道所有的具体的同事类,即以一个集合来管理HashMap. 并接收某个具体同事对象消息, 完成相应的任务.
  6. - Colleague 是抽象同事类
  7. - ConcreteColleague 具体的同事类,会有很多,每个同事只知道自己的行为,而不了解其他同事类的行为(方法),但

是他们都依赖中介者对象

2.要点总结

宏观架构

  1. 1. 将多个对象间复杂的关联关系解耦,Mediator模式将多个对象间

的控制逻辑进行集中管理,变“多个对象互相关联”为“多个对象 和一个中介者关联”, 简化了系统的维护,抵御了可能的变化。

  1. 1. 随着控制逻辑的复杂化,Mediator具体对象的实现可能相当复杂。

这时候可以对Mediator对象进行分解处理。

  1. 1. **Facade模式是解耦系统间(单向)的对象关联关系; Mediator

式是解耦系统内各个对象之间(双向)的关联关系。**

微观代码

  1. 1. 多个类相互耦合,会形成网状结构, 使用中介者模式将网状结构分离为星型结构,

进行解耦

  1. 1. 减少类间依赖,降低了耦合,符合迪米特原则
  2. 1. **中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响**
  3. 1. 如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意

3.案例

需求

  1. - 智能家庭项目:
  2. 1. 智能家庭包括各种设备,闹钟、咖啡机、电视机、窗帘
  3. 1. 主人要看电视时,各个设备可以协同工作,自动完成看电视的准备工作,比如流

程为:闹铃响起->咖啡机开始做咖啡->窗帘自动落下->电视机开始播放

方案

  1. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1630232521400-2d5250a9-2acd-4397-91ac-644fc14c6080.png#clientId=u62794ef2-ec1d-4&from=paste&height=183&id=ufbc5e686&margin=%5Bobject%20Object%5D&name=image.png&originHeight=244&originWidth=384&originalType=binary&ratio=1&size=13379&status=done&style=none&taskId=u92384e8b-0bb1-4ca4-8acd-0d425445367&width=288)

分析

  1. 1. 当各电器对象有多种状态改变时,相互之间的调用关系会比较复杂
  2. 1. 各个电器对象彼此联系,你中有我,我中有你,不利于松耦合.
  3. 1. 各个电器对象之间所传递的消息(参数),容易混乱
  4. 1. 当系统增加一个新的电器对象时,或者执行流程改变时,代码的可维护性、扩展性

都不理想 ==>中介者模式

4.使用模式

方案

类图

  1. - ![image.png](https://cdn.nlark.com/yuque/0/2021/png/12524106/1630232925618-605b5da2-e0b2-40bf-a11f-b2659d735acb.png#clientId=u62794ef2-ec1d-4&from=paste&id=u7b858726&margin=%5Bobject%20Object%5D&name=image.png&originHeight=675&originWidth=1029&originalType=binary&ratio=1&size=319014&status=done&style=none&taskId=u42ff4ca7-3c1c-446e-8055-748b24a4745)

代码

  1. - 中介者
  1. public abstract class Mediator {
  2. //将同事对象,加入到集合中
  3. public abstract void Register(String colleagueName, Colleague colleague);
  4. //接收消息, 具体的同事对象发出
  5. public abstract void GetMessage(int stateChange, String colleagueName);
  6. public abstract void SendMessage();
  7. }
  8. //具体的中介者类
  9. public class ConcreteMediator extends Mediator {
  10. //集合,同事对象的容器
  11. private HashMap<String, Colleague> colleagueMap;
  12. private HashMap<String, String> interMap;
  13. public ConcreteMediator() {
  14. colleagueMap = new HashMap<String, Colleague>();
  15. interMap = new HashMap<String, String>();
  16. }
  17. // 注册同事对象
  18. @Override
  19. public void Register(String colleagueName, Colleague colleague) {
  20. // TODO Auto-generated method stub
  21. colleagueMap.put(colleagueName, colleague);
  22. // TODO Auto-generated method stub
  23. if (colleague instanceof Alarm) {
  24. interMap.put("Alarm", colleagueName);
  25. } else if (colleague instanceof CoffeeMachine) {
  26. interMap.put("CoffeeMachine", colleagueName);
  27. } else if (colleague instanceof TV) {
  28. interMap.put("TV", colleagueName);
  29. } else if (colleague instanceof Curtains) {
  30. interMap.put("Curtains", colleagueName);
  31. }
  32. }
  33. //具体中介者的核心方法
  34. //1. 根据得到消息,完成对应任务
  35. //2. 中介者在这个方法,协调各个具体的同事对象,完成任务
  36. @Override
  37. public void GetMessage(int stateChange, String colleagueName) {
  38. // TODO Auto-generated method stub
  39. //处理闹钟发出的消息
  40. if (colleagueMap.get(colleagueName) instanceof Alarm) {
  41. if (stateChange == 0) {
  42. ((CoffeeMachine) (colleagueMap.get(interMap
  43. .get("CoffeeMachine")))).StartCoffee();
  44. ((TV) (colleagueMap.get(interMap.get("TV")))).StartTv();
  45. } else if (stateChange == 1) {
  46. ((TV) (colleagueMap.get(interMap.get("TV")))).StopTv();
  47. }
  48. } else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
  49. ((Curtains) (colleagueMap.get(interMap.get("Curtains"))))
  50. .UpCurtains();
  51. } else if (colleagueMap.get(colleagueName) instanceof TV) {//如果TV发现消息
  52. } else if (colleagueMap.get(colleagueName) instanceof Curtains) {
  53. //如果是以窗帘发出的消息,这里处理...
  54. }
  55. }
  56. @Override
  57. public void SendMessage() {
  58. // TODO Auto-generated method stub
  59. }
  60. }
  1. - 同事类
  1. //同事抽象类
  2. public abstract class Colleague {
  3. private Mediator mediator;
  4. public String name;
  5. public Colleague(Mediator mediator, String name) {
  6. this.mediator = mediator;
  7. this.name = name;
  8. }
  9. public Mediator GetMediator() {
  10. return this.mediator;
  11. }
  12. public abstract void SendMessage(int stateChange);
  13. }
  14. // 具体同事们...
  15. public class Alarm extends Colleague {
  16. //构造器
  17. public Alarm(Mediator mediator, String name) {
  18. super(mediator, name);
  19. // TODO Auto-generated constructor stub
  20. //在创建Alarm 同事对象时,将自己放入到ConcreteMediator 对象中[集合]
  21. mediator.Register(name, this);
  22. }
  23. public void SendAlarm(int stateChange) {
  24. SendMessage(stateChange);
  25. }
  26. @Override
  27. public void SendMessage(int stateChange) {
  28. // TODO Auto-generated method stub
  29. //调用的中介者对象的getMessage
  30. this.GetMediator().GetMessage(stateChange, this.name);
  31. }
  32. }
  33. public class CoffeeMachine extends Colleague {
  34. public CoffeeMachine(Mediator mediator, String name) {
  35. super(mediator, name);
  36. // TODO Auto-generated constructor stub
  37. mediator.Register(name, this);
  38. }
  39. @Override
  40. public void SendMessage(int stateChange) {
  41. // TODO Auto-generated method stub
  42. this.GetMediator().GetMessage(stateChange, this.name);
  43. }
  44. public void StartCoffee() {
  45. System.out.println("It's time to startcoffee!");
  46. }
  47. public void FinishCoffee() {
  48. System.out.println("After 5 minutes!");
  49. System.out.println("Coffee is ok!");
  50. SendMessage(0);
  51. }
  52. }
  53. public class Curtains extends Colleague {
  54. public Curtains(Mediator mediator, String name) {
  55. super(mediator, name);
  56. // TODO Auto-generated constructor stub
  57. mediator.Register(name, this);
  58. }
  59. @Override
  60. public void SendMessage(int stateChange) {
  61. // TODO Auto-generated method stub
  62. this.GetMediator().GetMessage(stateChange, this.name);
  63. }
  64. public void UpCurtains() {
  65. System.out.println("I am holding Up Curtains!");
  66. }
  67. }
  68. public class TV extends Colleague {
  69. public TV(Mediator mediator, String name) {
  70. super(mediator, name);
  71. // TODO Auto-generated constructor stub
  72. mediator.Register(name, this);
  73. }
  74. @Override
  75. public void SendMessage(int stateChange) {
  76. // TODO Auto-generated method stub
  77. this.GetMediator().GetMessage(stateChange, this.name);
  78. }
  79. public void StartTv() {
  80. // TODO Auto-generated method stub
  81. System.out.println("It's time to StartTv!");
  82. }
  83. public void StopTv() {
  84. // TODO Auto-generated method stub
  85. System.out.println("StopTv!");
  86. }
  87. }
  1. - 测试
  1. public class ClientTest {
  2. public static void main(String[] args) {
  3. //创建一个中介者对象
  4. Mediator mediator = new ConcreteMediator();
  5. //创建Alarm 并且加入到 ConcreteMediator 对象的HashMap
  6. Alarm alarm = new Alarm(mediator, "alarm");
  7. //创建了CoffeeMachine 对象,并 且加入到 ConcreteMediator 对象的HashMap
  8. CoffeeMachine coffeeMachine = new CoffeeMachine(mediator,
  9. "coffeeMachine");
  10. //创建 Curtains , 并 且加入到 ConcreteMediator 对象的HashMap
  11. Curtains curtains = new Curtains(mediator, "curtains");
  12. TV tV = new TV(mediator, "TV");
  13. //让闹钟发出消息
  14. alarm.SendAlarm(0);
  15. coffeeMachine.FinishCoffee();
  16. alarm.SendAlarm(1);
  17. }
  18. }

5.经典使用


5.1