5.5-Mediator-中介者-行为型模式

目的

用一个中介对象封装对象交互,使各对象不需要显式地相互引用

  • 从而可以解耦合
  • 可以对立改变之间的交互

示例

面向对象中,对象的行为分布到各个对象中。这种分布可能会导致对象间有许多连接。在最坏的情况下,每一个对象都知道其他所有对象。

考虑 GUI 中各个窗口组件的依赖关系:例如当一个特定的输入域为空时,某个按钮不能使用;ListBox 选择一项可能会改变一个输入域的内容

  • 这导致每个组件必须单独定制以反应组件间的依赖关系
  • 解决方法:可以通过将集体行为封装在一个单独的中介者(mediator)对象中,如下图所设

类层次结构: 对象交互: 例如选择 ListBox 改变 EntryField 的内容

适用性

  • 一组对象以定义良好但复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解。
  • 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
  • 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

结构

  • Mediator 中介者:定义和同事 Colleague 通信的接口
  • ConcreteMediator:了解并维护它的各个同事,处理它们之间的交互
  • Colleagueclass:
    • 每个同事均了解其中介对象(例如持有一份 Mediator 实例的引用)
    • 每个同事通过中介的接口与其他同事通信

同事向一个中介者对象发送和接收请求。中介者在各同事间适当地转发请求以实现协作行为

优缺点

  • 将各 Colleague 解耦
  • 简化了对象协议:用 Mediator 和各 Colleague 间的一对多交互来代替多对多交互,更易于理解、维护和扩展。
  • 对对象如何协作进行了抽象:将中介作为一个独立的概念并将其封装在一个对象中,使你将注意力从对象各自本身的行为转移到它们之间的交互上来。
  • 使控制集中化:中介者模式将交互的复杂性变为中介者的复杂性,这可能导致中介者本身复杂而难以维护

实现

  • 简单情形下无需定义抽象中介类:当各 Colleague 仅与一个 Mediator 一起工作时,没有必要定义一个抽象的 Mediator 类
  • Colleague-Mediator 通信:当一个感兴趣的事件发生时, Colleague 必须与其 Mediator 通信,这有两种实现方法:
    • 使用 Observer(5.7) 模式,将 Mediator 实现为一个 Observer,各 Colleague 作为 Subject
      • 一旦 Subject 状态改变就发送通知给 Mediator
      • Mediator 将该事件向所有其他 Colleague 转发
    • 在 Mediator 中定义一个特殊的通知接口,各 Colleague 在通信时直接调用该接口

相关模式

Facade(4.5)与中介者的不同之处在于:

  • Facade 是对一个对象子系统进行抽象,从而提供了一个更为方便的接口。它的协议是单向的,即 Facade 对象对这个子系统类提出请求,但反之则不行。
  • Mediator 提供了各 Colleague 对象不支持或不能支持的协作行为,而且协议是多向的。

Colleague 可使用 Observer(5.7)模式与 Mediator 通信。