调解器模式优势

Mediator Pattern Advantage

提问人:Michael Maier 提问时间:5/31/2021 更新时间:5/31/2021 访问量:310

问:

我正在读 GoF 的书。您能否解释一下以下优势:

它限制了子类。调解员将原本会定位的行为定位 分布在多个对象中。更改此行为需要 仅子类化 Mediator;同事类可以按原样重用。

这是否意味着我们应该子类化中介或具体中介? 我们可以有多个 ConcreteMediator 继承同一个 Mediator 吗?

设计模式 与语言无关 的中介

评论


答:

0赞 Mark Seemann 5/31/2021 #1

这本书写于 1994 年或之前,主要有 C++ 的示例。因此,它大量使用继承,部分原因是 C++ 允许多重继承,部分原因是该语言没有单独的接口概念(如 Java 或 C#)。

在书的开头,它提出了一个目标:

优先于对象组合而不是类继承。

书中隐含的理解是,继承可能不是重用的最佳机制。

考虑为中介器模式提供的示例:字体对话框。如果没有 Mediator (),则需要直接了解 ,以便更新其状态更改。FontDialogDirectorListBoxEntryField

通用型应该在许多情况下都很有用,无论有没有协作。因此,可重用的类不能知道任何“同事”,因为这会使它不可重用。ListBoxEntryFieldListBox

因此,如果没有中介器,您需要子类以将其连接到 .在伪 C# 中,它可能如下所示:ListBoxEntryField

public class FontList : ListBox
{
    public FontList(EntryField entryField)
    {
        EntryField = entryField;
    }

    public EntryField EntryField { get; }

    protected override void Changed()
    {
        EntryField.Text = this.Selection;
    }
}

这是 Mediator 模式所限制的非常具体的子类类型。

这是否意味着我们应该子类化中介或具体中介?

也不。请注意,模式描述的 Implementation 小节指出:

省略抽象 Mediator 类。当同事只与一个中介一起工作时,无需定义抽象的 Mediator 类。Mediator 类提供的抽象耦合允许同事使用不同的 Mediator 子类,反之亦然。

该类充当同事的中心联系点。如果只有一个调解员,它可以是具体的。区别在于你如何传播变化。在此示例中,每个将更改传播到如下所示:MediatorWidgetDialogDirector

_director->WidgetChanged(this);

我们可以想象它应该是一个可重用的类,所以我们希望它与任何具体的中介解耦。在这里,假设可能不止一个。Widget

另一方面,如果你有一组专门的同事,他们不能重复使用,他们可以通过一个具体的调解人进行沟通。如果在这种情况下不需要重用,则 Mediator 不必是抽象类。

评论

0赞 Michael Maier 6/2/2021
在实现部分(在书中)中,您能解释一下我应该在哪里使用该部分吗?大体上?(我不擅长 C++)void Widget::Changed () { _director->WidgetChanged(this); }
0赞 Mark Seemann 6/2/2021
@MichaelMaier,我直接从本书的示例代码部分复制了那行代码,该部分解释了上下文。我已经有 20+ 年没有做过任何 C++ 了,所以我不确定,但 AFAICT 它覆盖了类的方法,我认为我们应该将其视为事件处理程序。WidgetChanged