调停者模式简介

良好设计的应用由轻量级的对象组合而成,这些对象具有特定的职责,符合SOILD 的单一职责原则。然而,这些大量轻量级的对象给应用带来好处的同时也带来了对象之间交互通信的挑战。对象间需要通信来完成业务需求,当对象数量不断增加时,通信很快变的很难管理。另外,对象之间通信需要感知对方的存在,紧耦合在一起的对象违反了 SOLID 原则。调停者模式被证明可以解决这样的问题。

调停者模式定义了一个调停者(Mediator)对象来处理对象之间的交互,进而替代一组对象之间直接交互。下图简单展示有无调停者模式对象之间交互的方式。


如上图显示,利用 Mediator 对象使应用中对象无限知道其他对象的存在,Mediator 封装了一个通信协议让对象遵循。
在系统中,Mediator 对象封装了对象之间的所有交互逻辑。因此,如果一个对象根据新的交互规则被修改或者一个新的对象被创建,只要修改Mediator 对象,如果没有Mediator 对象,你需要知道交互中的所有对象。通过使用 Mediator 对象使你的代码封装性更好,不会牵一发动全身。

调停者模式中的参与者

想象一下一个战区,武装部队正在向敌人的领土进发。 武装部队可以包括士兵,坦克,掷弹兵和狙击部队。 采用的策略是,每当一个单位进攻时,其他单位就应停止进攻并掩盖。 为此,当前正在攻击的部队需要通知其他部队。
在编程世界中,你可以通过为每个部队创建一个来为需求建模。当一个类对象代表的部队将要开始发起攻击时,你可以实现对其他类对象的通知逻辑。现在,假设一个新的作战部队加入时,结果是所有参与交互的类都要修改,更糟糕的情况是,当作战策略修改,可以同时多个作战部队发起攻击,这时修改的代码会更多。通上面介绍描述的一样,我们可以通过调停者模式解决。在阵营中放一个指挥官来充当调停者,所有作战部队通过指挥官交流,指挥官把收到的通知按需发送给其他的部队。
开始对上面的作战部队的例子建模,把指挥官定义成 Commander 接口,也就是 Mediator,类 CommanderImpl 实现接口 Commander, 接口定义了方法来发送消息。接口ArmedUnit 代表作战部队,实现类有 SoldierUnitTankUnit,实现类中引用了 Commander

调停者模式的代码实现

public interface Commander {void registerArmedUnits(ArmedUnit soldierUnit, ArmedUnit tankUnit);void setAttackStatus(boolean attackStatus);boolean canAttack();void startAttack(ArmedUnit armedUnit);void ceaseAttack(ArmedUnit armedUnit);
}public interface ArmedUnit {void attack();void stopAttack();
}public class SoldierUnit implements ArmedUnit {private final Commander commander;public SoldierUnit(Commander commander) {this.commander = commander;}@Overridepublic void attack() {if (commander.canAttack()) {System.out.println("SoldierUnit:Attacking...");commander.setAttackStatus(false);} else {System.out.println("SoldierUnit:Cannot attack now,other units are attacking... ");}}@Overridepublic void stopAttack() {System.out.println("SoldierUnit:Stop Attacking...");commander.setAttackStatus(true);}
}
public class TankUnit implements ArmedUnit {private final Commander commander;public TankUnit(Commander commander) {this.commander = commander;}@Overridepublic void attack() {if (commander.canAttack()) {System.out.println("TankUnit:Attacking...");commander.setAttackStatus(false);} else {System.out.println("TankUnit:Cannot attack now,other units are attacking....");}}@Overridepublic void stopAttack() {System.out.println("TankUnit:Stop attacking...");commander.setAttackStatus(true);}
}public class CommanderImpl implements Commander {private ArmedUnit soldierUnit, tankUnit;private boolean attackStatus = true;@Overridepublic void registerArmedUnits(ArmedUnit soldierUnit, ArmedUnit tankUnit) {this.soldierUnit = soldierUnit;this.tankUnit = tankUnit;}@Overridepublic void setAttackStatus(boolean attackStatus) {this.attackStatus = attackStatus;}@Overridepublic boolean canAttack() {return this.attackStatus;}@Overridepublic void startAttack(ArmedUnit armedUnit) {armedUnit.attack();}@Overridepublic void ceaseAttack(ArmedUnit armedUnit) {armedUnit.stopAttack();}
}public class CommanderImplTest {public static void main(String[] args) {Commander commander = new CommanderImpl();ArmedUnit soldierUnit = new SoldierUnit(commander);ArmedUnit tankUnit = new TankUnit(commander);commander.registerArmedUnits(soldierUnit, tankUnit);commander.startAttack(soldierUnit);commander.startAttack(tankUnit);commander.ceaseAttack(soldierUnit);commander.startAttack(tankUnit);}
}

调停者模式在 Spring 框架中的应用

在spring 中,Spring MVC 是调停者模式的最近实践,用 DispatcherServlet 链接 Controllers 。
下图是Spring MVC 官方给出的架构图


从上图可以看出,DispatcherServlet 在web 请求和Controllers 中间扮演了 mediator 的角色。Controllers 之间感知不到对方的存在,controller 无需知道web 请求的存在, view templates 也无需知道controller 和 request 的存在。 Front Controller 的职责是选择合适的controller 和 view template 去响应请求。
因为使用了调停者模式,controller 之间互不影响,web 请求对象发生变化,也不会影响到下游的controller 和 view。

总结

调停者模式是一个被广泛使用的模式,主要职责是封装了对象之间的通信逻辑。这个模式的缺点需要需求的变化,mediator 对象会逐渐变复杂。但是,通过 SOLID 原则的单一职责原则,你可以把 mediator 对象按职责分划分为多个类来协助完成原有对象的职责。

设计模式系列-调停者模式-Mediator相关推荐

  1. 《Java设计模式》之调停者模式(Mediator)

    调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从而使它们能够较松散地耦合.当这些对象中的某些对象之间的相互作用发生改变时,不会马上影响到其它的一些 ...

  2. 设计模式系列·抽象工厂模式

    前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...

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

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

  4. Java设计模式系列--责任链模式(应用)

    原文网址:Java设计模式系列--责任链模式(应用)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Java设计模式中的责任链模式的一些使用场景. 责任链模式的好处 符合单一职责原则 每个功能 ...

  5. 设计模式系列之建造者模式构建实体类

    设计模式系列之建造者模式(Build Pattern)构建实体类 模式定义 建造者模式属于23种设计模式中的创建型模式,可以理解为创建对象的一种很好的方法. 所谓建造者模式就是**将组件和组件的组件过 ...

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

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

  7. java手动切换成独立显卡_JAVA设计模式之调停者模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从 ...

  8. 调停者模式 java_JAVA设计模式之调停者模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从 ...

  9. JAVA设计模式之调停者模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从 ...

最新文章

  1. PCL滤波介绍(3)
  2. python实现自动发送微博,当自己写博客时同步上去。
  3. 虚拟机无法开机数据恢复 (建议在做之前做测试,数据双重备份)
  4. 专家谈家教中的心理健康教育
  5. 谈谈writev的问题
  6. Android数据库 分页查询,Android之怎么使用SQLite数据库(增、删、改、查、分页等)以及ListView显示数据(转)...
  7. ubuntu下使用openocd+jlink进行STM32开发调试
  8. 利用dbms_metadata.get_ddl查看DDL语句
  9. 带你自学Python系列(十四):Python函数的用法(四)
  10. Swift 类的使用class
  11. Robo 可视化mongoDb的操作
  12. 【微软雅黑字体的简单介绍】
  13. yandex.com搜索等级、限制设置
  14. verilog 实战 与非门
  15. HTML基础笔记——head标签
  16. 如何使用 Swift 开发简单的条形码检测器?
  17. h5课件制作_PPT轻松转化H5,让“课件”动起来!
  18. 弘辽科技:拼多多推广单元和推广计划是一样的吗?
  19. python保存图片格式_python 存储网页图片格式
  20. 给博客增加豆瓣观影和阅读

热门文章

  1. Centos7.3-Oracle11g数据库静默部署
  2. seo原创文章五种方法迎合搜索引擎收录和排名
  3. zendstiduo背景色设置为保护眼睛的颜色》》》
  4. 普通人如何做到“我命由我不由天”
  5. 阿里巴巴宣布入股B站 持股比例约8%
  6. 35岁的程序员被优化,是市场经济的必然选择吗
  7. 东南大学计算机类专业排名,东南大学优势专业排名,2021年东南大学最好的专业排名...
  8. 【IPD】敏捷开发与IPD结合的实践培训课程「3月11-12日」
  9. 5-06特征变换代码
  10. 基于.NET6的简单三层管理系统