Observer и Pub-sub, наверное самые известные паттерны взаимодействия в мире разработки интерфейсов и JavaScript. Но несмотря на свою известность, некоторые разработчики считают эти паттерны одинаковыми, что и послужило подспорьем написать данную статью.

Существует довольно много шаблонов проектирования, например, фасад, фабрика, адаптер, мост и др. Считается, что каждый разработчик применяет паттерны проектирования, просто решая повседневные задачи, при этом возможно он даже и не знает об их существовании. Например, такие паттерны, как фасад, фабрика или адаптер, вполне можно применять даже не изучая их, т.к. они довольно элементарные и являются логическим заключением при решении каких-либо задач. На мой взгляд, лучший паттерн — это наличие мозга в голове и желания сделать качественный продукт, ведь паттерны сами по себе не являются конечным решением, �� дают всего лишь общее решение для типичных задач.
Но в мире интерфейсов и асинхронного JavaScript не возможно прожить без знания паттернов observer и pub-sub, так как знание и понимание этих шаблонов, значительно облегчает жизнь разработчику.
Observer и Pub-sub относятся к поведенческим паттернам (паттернам взаимодействия), т.е. применяются, когда требуется организовать взаимодействие между различными объектами системы.
Observer представляет собой не что иное, как связь один-ко-многим. В упрощенном виде этот паттерн состоит из объекта наблюдения (subject) и наблюдателей (observers).
Принципиальная схема взаимодействия выглядит так:
Subject — реализует методы: observe, detach, notify, get, set.
Observer — реализует метод update.
Также subject содержит ссылки на всех observers, которые его слушают, а observer, в свою очередь содержит ссылку, на subject, на который он подписан.
Таким образом в этом паттерне наблюдается прямая связь между объектами, т.е. subject знает о всех своих observers и вручную оповещает их о происходящих в себе изменениях, вызывая метод update у каждого observer. Связь устанавливается методом observe, разрывается методом detach.
Subject хранит внутри себя свое состояние и все действия с его состоянием необходимо совершать используя get/set методы, чтобы при изменениях состояния вызывать метод notify. Подобная схема реализована в EmberJs.
Observer можно представить довольно неплохой картинкой (заимствовано тут):

Примерную реализацию можно найти на сайте Addy Osmani.
Pub-sub паттерн является одной из вариаций паттерна Observer. Исходя из названия в паттерне выделяют два компонента Publisher (издатель) и Subscriber (подписчик). В отличие от Observer, связь между объектами осуществляется посредством канала связи Event Channel (шины событий).
Publisher кидает свои события в Event Channel, а Subscriber подписывается на нужное событие и слушает его на шине, что обеспечивает отсутствие прямой связи между подписчиком и издателем.
Схематично Pub-sub и отличие от Observer, можно представить так:

Таким образом можно выделить основные отличительные особенности между Pub-sub и Observer:
Одной из наиболее известных реализаций паттерна pub-sub является Backbone, AmplifyJs и др. DOM, в некоторой степени тоже реализует модель pub-sub.
На основе pub-sub строится работа паттерна Mediator, который позволяет наладить коммуникацию между различными компонентами системы. Mediator представляет собой глобальный объект в системе, о котором знают все компоненты системы, при этом компонент может выступать как слушателем события, так и издателем другого события, таким образом налаживая коммуникацию между объектами системы.
Если провести аналогию, то Mediator это городская АТС, в которую приходят входящие и исходящие вызовы от абонентов, а доходят они строго до нужного абонента. Но как мы знаем у телефонной сети есть недостаток — на новый год она может оказаться перегруженной огромным количеством звонков и перестать доставлять вызова абонентам. Тоже самое может произойти и с Mediator, когда он не справится с потоком событий.
Mediator особенно полезен в тех случаях, когда наблюдаются множественные однонаправленные или двунаправленные связи между различными компонентами системы. Особенно паттерн полезен, когда в приложении имеются вложенные друг в друга компоненты системы (например, дочерние композиционные элементы), чтобы не было необходимости пробрасывать callbacks используя модель всплытия события изнутри наружу. Достаточно предоставить Mediator внутреннему компоненту, который опубликует свое событие, а другие компоненты узнают об этом событии.
Mediator паттерн довольно успешно реализован в Backbone — сам глобальный объект Backbone можно использовать в качестве Mediator, либо унаследоваться от Backbone.Events.
Когда и где следует применять каждый паттерн — дело каждого, но прежде чем применять, следует понять их отличия и особенности. Например, Observer паттерн представляет собой прямую связь между объектами и сигнализирует наблюдателю об изменении своего состояния. На мой взгляд, данный паттерн очень хорошо подходит при разработке различных форм с множеством полей ввода, когда необходимо реагировать на изменения значений полей формы (binding).
Пат��ерн Mediator, как уже было отмечено, особенно полезен, когда необходимо наладить однонаправленную или двунаправленную связь между разрозненными компонентами системы, например, в сложных интерфейсах с множеством композиционных элементов, когда необходимо пробросить событие из вложенного view наверх, чтобы в другом view отобразить какую-либо информацию или выполнить действие, зависящее от этого события.

Существует довольно много шаблонов проектирования, например, фасад, фабрика, адаптер, мост и др. Считается, что каждый разработчик применяет паттерны проектирования, просто решая повседневные задачи, при этом возможно он даже и не знает об их существовании. Например, такие паттерны, как фасад, фабрика или адаптер, вполне можно применять даже не изучая их, т.к. они довольно элементарные и являются логическим заключением при решении каких-либо задач. На мой взгляд, лучший паттерн — это наличие мозга в голове и желания сделать качественный продукт, ведь паттерны сами по себе не являются конечным решением, �� дают всего лишь общее решение для типичных задач.
Но в мире интерфейсов и асинхронного JavaScript не возможно прожить без знания паттернов observer и pub-sub, так как знание и понимание этих шаблонов, значительно облегчает жизнь разработчику.
Observer и Pub-sub относятся к поведенческим паттернам (паттернам взаимодействия), т.е. применяются, когда требуется организовать взаимодействие между различными объектами системы.
Observer
Observer представляет собой не что иное, как связь один-ко-многим. В упрощенном виде этот паттерн состоит из объекта наблюдения (subject) и наблюдателей (observers).
Принципиальная схема взаимодействия выглядит так:
Subject — реализует методы: observe, detach, notify, get, set.
Observer — реализует метод update.
Также subject содержит ссылки на всех observers, которые его слушают, а observer, в свою очередь содержит ссылку, на subject, на который он подписан.
Таким образом в этом паттерне наблюдается прямая связь между объектами, т.е. subject знает о всех своих observers и вручную оповещает их о происходящих в себе изменениях, вызывая метод update у каждого observer. Связь устанавливается методом observe, разрывается методом detach.
Subject хранит внутри себя свое состояние и все действия с его состоянием необходимо совершать используя get/set методы, чтобы при изменениях состояния вызывать метод notify. Подобная схема реализована в EmberJs.
Observer можно представить довольно неплохой картинкой (заимствовано тут):

Примерную реализацию можно найти на сайте Addy Osmani.
Pub-sub
Pub-sub паттерн является одной из вариаций паттерна Observer. Исходя из названия в паттерне выделяют два компонента Publisher (издатель) и Subscriber (подписчик). В отличие от Observer, связь между объектами осуществляется посредством канала связи Event Channel (шины событий).
Publisher кидает свои события в Event Channel, а Subscriber подписывается на нужное событие и слушает его на шине, что обеспечивает отсутствие прямой связи между подписчиком и издателем.
Схематично Pub-sub и отличие от Observer, можно представить так:

Таким образом можно выделить основные отличительные особенности между Pub-sub и Observer:
- отсутствие прямой связи между объектами
- объекты сигнализируют друг другу событиями, а не состояниями объекта
- возможность подписываться на различные события на одном объекте с различными обработчиками
Одной из наиболее известных реализаций паттерна pub-sub является Backbone, AmplifyJs и др. DOM, в некоторой степени тоже реализует модель pub-sub.
Mediator
На основе pub-sub строится работа паттерна Mediator, который позволяет наладить коммуникацию между различными компонентами системы. Mediator представляет собой глобальный объект в системе, о котором знают все компоненты системы, при этом компонент может выступать как слушателем события, так и издателем другого события, таким образом налаживая коммуникацию между объектами системы.
Если провести аналогию, то Mediator это городская АТС, в которую приходят входящие и исходящие вызовы от абонентов, а доходят они строго до нужного абонента. Но как мы знаем у телефонной сети есть недостаток — на новый год она может оказаться перегруженной огромным количеством звонков и перестать доставлять вызова абонентам. Тоже самое может произойти и с Mediator, когда он не справится с потоком событий.
Mediator особенно полезен в тех случаях, когда наблюдаются множественные однонаправленные или двунаправленные связи между различными компонентами системы. Особенно паттерн полезен, когда в приложении имеются вложенные друг в друга компоненты системы (например, дочерние композиционные элементы), чтобы не было необходимости пробрасывать callbacks используя модель всплытия события изнутри наружу. Достаточно предоставить Mediator внутреннему компоненту, который опубликует свое событие, а другие компоненты узнают об этом событии.
Mediator паттерн довольно успешно реализован в Backbone — сам глобальный объект Backbone можно использовать в качестве Mediator, либо унаследоваться от Backbone.Events.
Что? Где? Когда?
Когда и где следует применять каждый паттерн — дело каждого, но прежде чем применять, следует понять их отличия и особенности. Например, Observer паттерн представляет собой прямую связь между объектами и сигнализирует наблюдателю об изменении своего состояния. На мой взгляд, данный паттерн очень хорошо подходит при разработке различных форм с множеством полей ввода, когда необходимо реагировать на изменения значений полей формы (binding).
Пат��ерн Mediator, как уже было отмечено, особенно полезен, когда необходимо наладить однонаправленную или двунаправленную связь между разрозненными компонентами системы, например, в сложных интерфейсах с множеством композиционных элементов, когда необходимо пробросить событие из вложенного view наверх, чтобы в другом view отобразить какую-либо информацию или выполнить действие, зависящее от этого события.
Почитать
- Learning Javascript Design Patters, Addy Osmani
- Programming in the large with Design Patterns, Eddie Burris
- Примеры кода
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Observer отличается от Pub-sub?
62.09%Да339
6.23%Нет34
31.68%Это философский вопрос173
Проголосовали 546 пользователей. Воздержались 88 пользователей.
