Я читал « Банду четырех» , чтобы решить некоторые из моих проблем, и наткнулся на шаблон « Посредник» .
Раньше я использовал Observer в своих проектах для создания приложения с графическим интерфейсом. Я немного сбит с толку, так как не вижу большой разницы между ними. Я просмотрел, чтобы найти разницу, но не смог найти подходящего ответа на свой запрос.
Может ли кто-нибудь помочь мне провести различие между ними на каком-нибудь хорошем примере, который четко их разграничивает?
Programmers.StackExchange
была отклонена, но я сделал похожий пост, потому что меня интересовал ответ. Вы можете найти некоторые ответы интересными. :)ChangeManager
дляObserver
шаблона , который используетMediator
. увидеть; paginas.fe.up.pt/~aaguiar/as/gof/hires/pat5g.htm#samplecodeОтветы:
Шаблон наблюдателя: определяет зависимость «один ко многим» между объектами, так что, когда один объект меняет состояние, все его зависимые объекты автоматически уведомляются и обновляются.
Шаблон посредника: определите объект, который инкапсулирует, как взаимодействует набор объектов. Посредник способствует слабой связи, не позволяя объектам явно ссылаться друг на друга, и позволяет вам изменять их взаимодействие независимо.
Источник: dofactory
Пример:
Шаблон наблюдателя: класс A, может иметь ноль или более зарегистрированных наблюдателей типа O. Когда что-то в A изменяется, это уведомляет всех наблюдателей.
Шаблон посредника: у вас есть некоторое количество экземпляров класса X (или, возможно, даже несколько разных типов: X, Y и Z), и они хотят общаться друг с другом (но вы не хотите, чтобы каждый имел явные ссылки на каждый other), поэтому вы создаете класс-посредник M. Каждый экземпляр X имеет ссылку на общий экземпляр M, через который он может взаимодействовать с другими экземплярами X (или X, Y и Z).
источник
В оригинальной книге, в которой были введены термины «наблюдатель» и «посредник», « шаблоны проектирования», «элементы многоразового объектно-ориентированного программного обеспечения» , говорится, что шаблон «посредник» может быть реализован с использованием шаблона «наблюдатель». Однако это также может быть реализовано, если у коллег (которые примерно эквивалентны субъектам шаблона наблюдателя) есть ссылка либо на класс посредника, либо на интерфейс посредника.
Есть много случаев, когда вы хотите использовать шаблон наблюдателя, ключевой момент в том, что объект не должен знать, какие другие объекты наблюдают за его состоянием.
Посредник немного более конкретен, он избегает прямого общения классов, а вместо этого через посредника. Это помогает принципу единой ответственности, позволяя передавать коммуникацию классу, который просто занимается коммуникацией.
Классический пример посредника находится в графическом интерфейсе, где наивный подход может привести к появлению кода события нажатия кнопки, говорящего: «если панель Foo отключена, а панель Bar имеет метку с надписью« Пожалуйста, введите дату », тогда не вызывайте сервер, в противном случае - вперед », где с шаблоном« Посредник »можно было бы сказать:« Я всего лишь кнопка и не имею никаких земных дел, зная о панели Foo и ярлыке на панели Bar, поэтому я просто спрошу своего посредника, звонит ли сервер. в порядке прямо сейчас ".
Или, если Посредник реализован с использованием паттерна Наблюдатель, кнопка будет говорить «Привет, наблюдатели (включая посредника), мое состояние изменилось (кто-то щелкнул меня). Сделайте что-нибудь с этим, если вам не все равно». В моем примере это, вероятно, имеет меньше смысла, чем прямая ссылка на посредника, но во многих случаях использование шаблона Observer для реализации Mediator будет иметь смысл, и разница между Observer и Mediator будет больше связана с намерением, чем с различием в самом коде.
источник
Наблюдатель
1. Без
Client1 : Привет, тема , когда ты меняешься ?
Client2 : Когда вы сменили тему ? Я не заметил!
Клиент3 : Я знаю, что тема изменилась.
2. С
Посредник
1. Без
2. С
источник
Эти шаблоны используются в разных ситуациях:
Шаблон посредника используется, когда у вас есть две подсистемы с некоторой зависимостью, и одна из них требует изменения, и, поскольку вы можете не захотеть изменять систему, которая зависит от другой, вы можете захотеть ввести посредника, который будет разъединить зависимость между ними. Таким образом, при изменении одной из подсистем все, что вам нужно сделать, это обновить посредник.
Шаблон наблюдателя используется, когда класс хочет разрешить другим классам регистрироваться и получать уведомления о событиях, например, ButtonListener и т. Д.
Оба этих шаблона допускают меньшее сцепление, но они совершенно разные.
источник
Давайте рассмотрим пример: представьте, что вы хотите создать два приложения:
посредник
Создавая приложение для чата, вы будете выбирать
mediator
шаблон проектирования.Почему мы предпочтем
mediator
? просто взгляните на его определение:Как работает магия? Сначала мы создадим посредника чата и заставим объекты лиц регистрироваться в нем, чтобы у него было двухстороннее соединение с каждым отдельным человеком (человек может отправлять сообщение с помощью посредника чата, потому что у него есть доступ к нему, а посредник чата будет иметь доступ к нему). полученный метод объекта человека, потому что он также имеет к нему доступ)
наблюдатель
Создавая приложение для вызова службы экстренной помощи, вы будете выбирать
observer
шаблон проектирования.observer
объект скорой помощи хочет быть проинформирован о возникновении чрезвычайной ситуации, чтобы он мог проехать по адресу и оказать помощь.observable
отслеживает каждую машину скорой помощиobservers
и уведомляет их, когда требуется помощь (или возникает событие).Почему мы предпочтем
observer
? просто взгляните на его определение:Различия:
mediator
есть двусторонняя связь между объектами-людьми (отправка и получение), тогда как у оператораobservable
есть только односторонняя связь (он говорит машине скорой помощиobserver
ехать и финишировать).mediator
может заставить объекты людей взаимодействовать между ними (даже если это не прямое общение), машины скорой помощиobservers
регистрируются только наobservable
события оператора .mediator
, а также чатmediator
сохраняет ссылку на каждого человека. Там, где скорая помощьobserver
не ссылается на оператораobservable
, только операторobservable
ссылается на каждую машину скорой помощиobserver
.источник
Хотя оба они используются для организованного способа сообщения об изменениях состояния, они немного отличаются структурно и семантически IMO.
Наблюдатель используется для трансляции изменения состояния конкретного объекта из самого объекта. Таким образом, изменение происходит в центральном объекте, который также отвечает за передачу сигналов. Однако в Mediator изменение состояния может произойти в любом объекте, но оно транслируется посредником. Так что есть разница в потоке. Но я не думаю, что это влияет на поведение нашего кода. Мы можем использовать одно или другое для достижения того же поведения. С другой стороны, это различие может повлиять на концептуальное понимание кода.
Видите ли, основная цель использования шаблонов - это скорее создание общего языка между разработчиками. Итак, когда я вижу посредника, я лично понимаю, что несколько элементов пытаются взаимодействовать через одного брокера / концентратора, чтобы уменьшить коммуникационный шум (или продвигать SRP), и каждый объект одинаково важен с точки зрения способности сигнализировать об изменении состояния. Например, представьте, что к аэропорту приближается несколько самолетов. Каждый должен общаться через пилон (посредник), а не друг с другом. (Представьте, что 1000 самолетов связываются друг с другом при посадке - это было бы беспорядком)
Однако, когда я вижу наблюдателя, это означает, что есть некоторые изменения состояния, которые меня могут волновать, и я должен зарегистрироваться / подписаться, чтобы прослушивать определенные изменения состояния. За сигнализацию изменений состояния отвечает центральный объект. Например, если мне важен конкретный аэропорт на пути из пункта А в пункт Б, я могу зарегистрироваться в этом аэропорту, чтобы транслировать некоторые события, например, пустая взлетно-посадочная полоса или что-то в этом роде.
Надеюсь, это ясно.
источник
@cdc превосходно объяснил разницу в намерениях.
Я добавлю немного информации поверх него.
Наблюдатель : включает уведомление о событии в одном объекте для разных наборов объектов (экземпляров разных классов)
Посредник : Централизуйте связь между набором объектов, созданных из определенного класса.
Структура паттерна Медиатор от дофабрики :
Посредник : определяет интерфейс для связи между коллегами.
Коллега : абстрактный класс, который определяет события, которые будут передаваться между коллегами.
ConcreteMediator : реализует кооперативное поведение, координируя объекты коллег и поддерживая своих коллег.
ConcreteColleague : реализует операции уведомления, полученные через посредника , которые были созданы другим коллегой.
Один пример из реального мира:
Вы обслуживаете сеть компьютеров в топологии Mesh . Если добавлен новый компьютер или удален существующий компьютер, все остальные компьютеры в этой сети должны знать об этих двух событиях.
Посмотрим, как в него вписывается паттерн Посредник.
Фрагмент кода:
выход:
Пояснение:
источник
Как насчет этого объяснения Технически Observer и Mediator одинаковы и используются для обеспечения независимого взаимодействия компонентов, но их использование отличается.
В то время как
obeserver
уведомляет подписанные компоненты об изменениях состояния (например, о создании новой записи в базе данных),mediator
команды зарегистрировали компоненты для выполнения каких-либо действий, связанных с потоком бизнес-логики (отправка электронной почты пользователю для сброса пароля).Наблюдатель
Посредник
источник