Посредник против Наблюдателя?

27

Может ли кто-нибудь дать мне канонический ответ о различиях между « Observerа» и «а» Mediatorи краткую информацию о том, когда вы должны использовать один шаблон над другим?

Я не уверен в том, какая ситуация ObserverпотребуетMediator

Рейчел
источник
Я хотел бы узнать ваше собственное представление об этом после 7 лет?
Niing

Ответы:

19

В оригинальной книге, в которой использованы термины «Наблюдатель» и «Посредник», « Шаблоны проектирования», «Элементы многоразового объектно-ориентированного программного обеспечения», говорится, что шаблон «Посредник» может быть реализован с использованием шаблона «Наблюдатель». Однако это также может быть реализовано с помощью ссылки «Коллеги» (примерно эквивалентной шаблону «Предметы наблюдателя») либо на класс Mediator, либо на интерфейс Mediator.

Есть много случаев, когда вы хотели бы использовать паттерн наблюдателя, ключ к которому заключается в том, что объект не должен знать, что другие объекты наблюдают за его состоянием.

Посредник немного более конкретен, он избегает прямого общения классов, а не посредника. Это помогает принципу единой ответственности, позволяя передавать информацию в класс, который этим занимается.

Классический пример посредника - в графическом интерфейсе, где наивный подход может привести к коду на событии нажатия кнопки, говорящем «если панель Foo отключена и панель« Панель »имеет метку с надписью« Пожалуйста, введите дату », то не вызывайте сервер», в противном случае продолжайте », где с помощью шаблона« Посредник »можно было бы сказать:« Я просто кнопка, и у меня нет ничего общего с панелью Foo и надписью на панели Bar, поэтому я просто спрошу своего посредника, звонит ли сервер сейчас нормально. "

Или, если это реализовано с использованием шаблона наблюдателя, кнопка скажет: «Эй, наблюдатели (включая посредника), мое состояние изменилось (кто-то щелкнул меня). Сделайте что-нибудь с этим, если вам не все равно». В моем примере это, вероятно, имеет меньше смысла, но иногда так и будет, и разница между Observer и Mediator будет больше выражать намерение, чем разницу в самом коде.

PSR
источник
Спасибо, ваши примеры действительно помогли мне прояснить разницу между ними. Если я вас правильно понимаю, шаблон наблюдателя использует для общения систему подписки / широковещания, в то время как посредник подобен некоторому глобально доступному объекту, объекты которого могут запрашивать информацию.
Рейчел
@ Рейчел - я бы описал наблюдателя, как ты. Посредник, вероятно, не является глобальным, но известен всем объектам в наборе, которые могли бы общаться друг с другом, но теперь проходят через посредника. Если посредник не реализован в качестве наблюдателя, в этом случае он знает обо всех этих объектах (по крайней мере, через их наблюдаемый интерфейс, может быть, напрямую), но они не знают об этом.
PSR
9

Шаблон Observer хорошо работает , когда нет координации между наблюдателями не является необходимым и наблюдает отношения идут в одну сторону.

Например, пусть объекты B и C наблюдают объект A. Когда объект A запускает событие X, тогда объект B должен выполнять метод Y (), а объект C должен выполнять метод Z (). Если методы BY () и CZ () полностью независимы и не требуют координации, тогда продолжайте и используйте шаблон наблюдателя.

С другой стороны, если BY () должен быть выполнен до CZ (), тогда вы захотите использовать шаблон Mediator, где посредник инкапсулирует эту координацию. В этом сценарии посредник M будет наблюдать объект A и будет иметь ссылки на объекты B и C. Когда A запускает событие X, M будет обрабатывать событие и вызывать BY () и CZ () в установленном порядке.

Кроме того, если объектам A, B и C необходимо наблюдать друг за другом, то использование посредника в качестве посредника будет иметь большое значение для разделения этих объектов и избежания спагетти-кода.

Рэймонд Салтрелли
источник
5

ObserverШаблон используется , когда действие , предпринимаемые на одном классе (наблюдаемый класс) должен произвести реакцию в другом классе (класс наблюдений) , но это нежелательно для наблюдаемого класса быть связан с классом наблюдения. Это очень распространенная модель. Парсер SAX XML может быть хорошим примером. Чтобы использовать парсер SAX, клиент реализует ContentHandlerинтерфейс для «наблюдения» за операцией парсера. Когда синтаксический анализатор сталкивается с элементами документа XML, он вызывает методы ContentHandler. Анализатор может вызывать код клиента, но анализатор не связан с кодом клиента.

MediatorШаблон является инкапсуляцией рисунка использования набора объектов. Код клиента связан только с медиатором, а не с несколькими другими классами. Это похоже на агрегацию, за исключением того, что время жизни инкапсулированных объектов не зависит от времени жизни посредника.

Кевин Клайн
источник
1

Проще говоря (что я использую, чтобы запомнить это):

Наблюдатель: Используйте, когда один объект хочет быть информированным об изменениях состояния в другом (строго говоря, использование событий - это Наблюдатель)

Чтобы понять посредника, мне будет проще, если вы сначала рассмотрите Facade: Facade объединяет функциональность отдельных классов (иногда целых подсистем) и предоставляет эту функциональность в едином интерфейсе.

Посредник: То же, что и Facade, за исключением того, что он объединяет функциональность всех агрегатных классов для создания новых функциональных возможностей. (Хорошее объяснение здесь )

Стивен Эверс
источник