本书写于 1994 年或之前,主要以 C++ 编写示例。因此,它大量使用继承,部分原因是 C++ 允许多重继承,部分原因是该语言没有单独的接口 概念(如 Java 或 C#)。
在本书的开头,它作为一个目标声明:
优先考虑对象组合而不是类继承。
书中隐含的理解是继承可能不是重用的最佳机制。
考虑为中介者模式给出的示例:字体对话框。如果没有调解器 (FontDialogDirector),ListBox 需要直接了解 EntryField 才能更新其状态变化。
通用的ListBox 应该在许多情况下都有用,无论有没有协作的EntryField。因此,一个可重用的 ListBox 类不能知道任何“同事”,因为这会使其不可重用。
因此,如果没有调解器,您需要继承 ListBox 以将其连接到 EntryField。在伪 C# 中,它可能看起来像这样:
public class FontList : ListBox
{
public FontList(EntryField entryField)
{
EntryField = entryField;
}
public EntryField EntryField { get; }
protected override void Changed()
{
EntryField.Text = this.Selection;
}
}
这是中介者模式所限制的非常特殊的子类化类型。
这是否意味着我们应该继承 Mediator 或 ConcreteMediator?
两者都没有。请注意,模式描述的 实施 小节指出:
省略抽象 Mediator 类。 当同事只使用一个中介时,无需定义抽象 Mediator 类。 Mediator 类提供的抽象耦合让同事可以使用不同的 Mediator 子类,反之亦然。
Mediator 类充当同事的中心联系点。如果只有一个调解员,它可以是具体的。区别在于你如何传播变化。在示例中,每个Widget 都将更改传播到其DialogDirector,如下所示:
_director->WidgetChanged(this);
我们可以想象Widget 应该是一个可重用的类,所以我们希望将它与任何具体的中介解耦。在这里,假设可能不止一个。
另一方面,如果您有一组专门的同事不可重用,他们可以通过具体的中介进行通信。如果在这种情况下不需要重用,则 Mediator 不必是抽象类。