通常,面向对象应用程序是由一组为了提供某种服务而彼此交互的对象组成。当彼此引用的对象数量比较少时,此时对象之间就为直接交互(点对点)。图31.1展示了当ObjectA和ObjectB之间彼此直接引用时的直接交互。 Figure 31.1: Point-to-Point Communication in the Case of Two Objects 当对象的数量增加时,这种直接交互会导致对象之间复杂的、混乱的引用(如图31.2)。这就会影响应用程序的可维护性。同时,因为对象之间的高耦合,当一个对象直接引用其他的对象时,缩小了这些对象的复用范围。
Figure 31.2: Point-toPoint Communication?Increased Number of Objects 在这种情况下,调停模式(Mediator Pattern)可以为这组对象设计一个控制、协调交互(交流)的模型,从而消除对象直接引用其他对象的需求。(如图31.3) Figure 31.3: Object Interaction?Mediator as a Communication Hub 调停者模式(Mediator Pattern)推荐抽象所有对象交互的细节到一个独立的类,这个类就是调停者,它负责这组对象之间的交互。这组对象中的每一个对象仍然负责提供它所具有的服务,但为了提供服务,对象之间不能直接彼此交互。两个不同对象之间的交互通过调停者(Mediator)进行路由。所有的对象把消息发送给调停者(Mediator)。调停者(Mediator)依据应用程序的需求把消息再发送给相应的对象。这样的设计有以下主要的优点: (1) 随着所有对象的交互行为移到一个独立的对象中,通过调停者(Mediator)的子类替换调停者(Mediator)或者改变它的功能可以很容易的改变对象之间内部的关联行为。 (2) 将对象的内部依赖关系移到一个单独的对象,这样会提高对象的可用性。 (3) 因为对象不需要直接引用其他的对象,所以对象可以更容易的进行单元测试。 (4) 类之间的低耦合可以使类在不影响其他类的基础上进行修改。 调停者(Mediator)模式和外观(Façade)模式 在一些方面调停者(Mediator)模式和外观(Façade)模式有相似之处。表31.1列出了两种模式之间的相似点和不同点。 Table 31.1: 调停者(Mediator)模式和外观(Façade)模式 在讨论命令模式的时候,我们建立了两个实验应用程序,让我们从新回顾这些应用程序,看一看应用调停者(Mediator,)模式如何避免对象与对象之间的直接交互。
例子1:
在前一章建立的FTP模拟客户应用程序有下面的客户UI组件(表31.2) Table 31.2: List of User Interface Objects and the Associated Functionality 图31.4描述了不同UI对象之间的交互。 Figure 31.4: Object Interaction 为了使现存应用程序对客户更加友好,让我们考虑如下的较小的改进。 (1) 当UI第一次显示,除了Exit按钮的所有按钮都是disabled的。 (2) 当从显示本地文件系统的JList控件中选择文件名时: A、 Upload和Delete按钮应该是enabled的。 B、 在远程文件系统中任何可选择的文件项目应该为不可选的(deselected). C、 Download按钮应该是disabled的。 (3) 当从显示远程文件系统的JList控件中选择文件名时: A、Download和Delete按钮应该是enabled的。 B、在本地文件系统中任何可选择的文件项目应该为不可选的(deselected). C、Upload按钮应该是disabled的。 D、当执行完必要的Upload/download操作之后,Upload、Download和Delete按钮应该为disabled的。同样,删除一个特定的文件后,Delete按钮应该为disabled的,同时Upload、Download按钮应该为enabled的。本地的和远程的文件系统在执行完Upload、Download和Delete操作后,应该进行刷新。 图31.5显示了对象之间交互的结果。 Figure 31.5: Object-to-Object Communication with Increased Direct Reference to Each Other 当更多的控件因增加功能而被添加,如重命名一个文件、FTP服务器连接、断开等,对象直接直接的交互在对象内部产生复杂的、混乱的对象引用。这很大程度上降低了应用程序的可维护性。 调停者模式可以被应用到这种情况,是一种对对象交互的高效的设计。应用调停者模式,一个描述对象之间交互细节的抽象被建立。这个抽象被设计为一个独立的Mediator类,如图31.6和Listing 31.1
Figure 31.6: Mediator Listing 31.1: Mediator Class