#design-patterns #language-agnostic #mediator
Вопрос:
Я читаю книгу Гофа. Не могли бы вы объяснить, пожалуйста, следующее преимущество:
Это ограничивает подклассы. Посредник локализует поведение, которое в противном случае было бы распределено между несколькими объектами. Для изменения этого поведения требуется только посредник подклассов; классы коллег могут быть повторно использованы как есть.
Означает ли это, что мы должны подклассировать Посредника или Конкретного Посредника? Можем ли мы иметь более одного конкретного посредника, которые наследуют один и тот же Посредник?
Ответ №1:
Книга написана в 1994 году или до этого, и в основном с примерами на C . Таким образом, он сильно использует наследование, отчасти потому, что C допускает множественное наследование, а отчасти потому, что в языке нет отдельной концепции интерфейса (например, Java или C#).
В начале книги говорится, что цель:
Отдавайте предпочтение композиции объектов, а не наследованию классов.
В книге подразумевается понимание того, что наследование может быть не лучшим механизмом для повторного использования.
Рассмотрим пример, приведенный для шаблона посредника: диалоговое окно шрифта. Без посредника ( FontDialogDirector
) ListBox
ему нужно было бы напрямую знать об EntryField
этом, чтобы сообщить ему об изменении его состояния.
Универсальное назначение ListBox
должно быть полезно во многих контекстах, с или без сотрудничества EntryField
. Таким образом, повторно ListBox
используемый класс не может знать ни о каких «коллегах», потому что это сделало бы его не подлежащим повторному использованию.
Таким образом, без посредника вам потребуется подкласс ListBox
, чтобы подключить его к an 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
Класс выступает в качестве центральной точки соприкосновения для коллег. Если есть только один Посредник, он может быть конкретным. Отличительный момент заключается в том, как вы распространяете изменения. В примере каждый Widget
из них распространяет изменения на свои DialogDirector
, как это:
_director->WidgetChanged(this);
Мы можем себе представить, что Widget
это должен быть многоразовый класс, поэтому мы хотели бы отделить его от любого конкретного посредника. Здесь предполагается, что их может быть несколько.
С другой стороны, если у вас есть специализированный набор коллег, которые не могут использоваться повторно, они могут общаться через конкретного посредника. Если повторное использование в этой ситуации не требуется, Посредник не обязательно должен быть абстрактным классом.
Комментарии:
1. в части реализации (в книге) не могли бы вы, пожалуйста, объяснить, где я должен использовать эту
void Widget::Changed () { _director->WidgetChanged(this); }
часть? В основном? (я не силен в c )2. @MichaelMaier Я скопировал эту строку кода прямо из раздела Примеров кода книги, в котором объясняется контекст. Прошло более 20 лет с тех пор, как я делал что-либо на C , поэтому я не уверен, но, возможно, это переопределяет метод
Widget
классаChanged
, который, я думаю, мы должны рассматривать как обработчик событий.