【问题标题】:Mediator Pattern Advantage中介者模式优势
【发布时间】:2021-08-18 04:42:26
【问题描述】:

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

它限制了子类化。中介者将原本会发生的行为本地化 分布在多个对象中。改变这种行为需要 仅子类化 Mediator;同事类可以按原样重复使用。

这是否意味着我们应该继承 Mediator 或 ConcreteMediator? 我们可以有多个继承自同一个 Mediator 的 ConcreteMediators 吗?

【问题讨论】:

    标签: design-patterns language-agnostic mediator


    【解决方案1】:

    本书写于 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 不必是抽象类。

    【讨论】:

    • 在实现部分(在书中)你能解释一下我应该在哪里使用void Widget::Changed () { _director->WidgetChanged(this); } 部分吗?主要是? (我不擅长 C++)
    • @MichaelMaier 我直接从书中的示例代码部分复制了那行代码,它解释了上下文。自从我做任何 C++ 以来已经 20 多年了,所以我不确定,但是 AFAICT 它覆盖了 Widget 类的 Changed 方法,我认为我们应该将其视为事件处理程序。
    猜你喜欢
    • 2014-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多