Это пост # 47 из серии, посвященный изучению JavaScript и его компонентов. В процессе определения и описания основных элементов мы также делимся некоторыми практическими правилами, которые мы используем при создании SessionStack, приложения JavaScript, которое должно быть надежным и высокопроизводительным, чтобы помочь компаниям оптимизировать цифровой опыт своих пользователей.

Введение

Возможность идентифицировать повторяющиеся шаблоны или темы в нашем коде является важным требованием для его оптимизации. И здесь понимание паттернов проектирования неоценимо.

Шаблоны проектирования - это многократно используемые решения общих проблем проектирования программного обеспечения.

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

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

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

Концепция шаблона проектирования давно присутствует в программировании, но в менее формальной форме. Однако в 1995 году группа, широко известная как банда четырех или GoF, опубликовала свою книгу Шаблоны проектирования: элементы многоразового объектно-ориентированного программного обеспечения.

Эта публикация GoF способствовала росту популярности шаблонов проектирования в разработке программного обеспечения, и на сегодняшний день она часто считается самой знаковой публикацией шаблонов проектирования.

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

Вы можете узнать больше об этих шаблонах и о том, зачем они нужны, в предыдущей статье, в которой говорилось о шаблонах проектирования в более общем плане.

В этой статье мы сосредоточимся на модели "издатель-подписчик". Давайте начнем с обзора в следующем разделе.

Образец наблюдателя

Шаблон наблюдателя - это шаблон проектирования, в котором вы определяете отношение «один ко многим» от одного объекта, известного как субъект, ко многим другим объектам, известным как наблюдатели.

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

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

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

Шаблон наблюдателя состоит из объекта, который отслеживает всех наблюдателей, которые в настоящее время на него подписаны. Тема также содержит методы, которые упрощают добавление, удаление и уведомление этих зависимых объектов.

Ниже представлена ​​простая реализация паттерна наблюдателя:

В приведенном выше коде конструктор Subject поддерживает список наблюдателей. И мы добавили соответствующие методы в прототип Subject. Это позволяет нам использовать эти методы для каждого экземпляра Subject.

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

В приведенном выше коде метод subscribe добавляет наблюдателей в массив observers, а метод unsubscribe удаляет наблюдателей из массива observers. Метод notify будет уведомлять указанного подписанного наблюдателя, а метод notifyAll уведомляет всех подписанных наблюдателей.

В шаблоне наблюдателя каждый наблюдатель должен подписаться на объект, запускающий событие - субъект, прежде чем он сможет получить уведомление. Однако шаблон pub / sub этого не требует. В шаблоне pub / sub используется промежуточное программное обеспечение, которое находится между объектами, запускающими событие. В этом случае издатели и подписанные объекты или подписчики. Давайте углубимся в шаблон дизайна pub / sub в следующем разделе.

Подробное описание модели "издатель-подписчик"

Шаблон pub / sub включает промежуточное программное обеспечение, которое также называется брокером pub / sub. Брокер pub / sub обрабатывает взаимодействие между издателями и подписчиками. Издатели публикуют контент или публикации для брокера публикации / подписки, и он обрабатывает доставку этого контента соответствующему подписчику.

Брокер pub / sub также обеспечивает свободное разделение издателей и подписчиков и поддерживает отношения от многих до многих между издателями и подписчиками.

Итак, в отличие от шаблона наблюдателя, шаблон pub / sub допускает использование нескольких издателей и нескольких подписчиков.

В шаблоне публикация / подписка издатель публикует содержимое в теме, и заинтересованные подписчики получают доступ к этому содержимому, отправляя подписки брокеру публикации / подписки для подписки на эту тему. Кроме того, в отличие от шаблона наблюдателя, и издателям, и подписчикам не нужно знать друг о друге.

Рассмотрим изображение ниже:

Существует множество реализаций шаблонов pub / sub, некоторыми примерами являются IBM Websphere MQ, RabbitMQ и RocketMQ, Apache Kafka, Google Cloud Pub / Sub и Pushy.

В этой статье мы реализуем базовую систему с использованием JavaScript.

Язык JavaScript хорошо подходит для шаблона pub / sub, потому что по своей сути большинство реализаций ECMAScript управляются событиями.

Наша реализация pub / sub состоит из pub / sub class, который содержит массив событий, который используется для поддержки списка всех опубликованных событий.

Кроме того, pub / sub class имеет метод subscription, который обрабатывает все взаимодействия между издателями и подписчиками.

Давайте посмотрим на реализацию ниже:

В нашем небольшом примере выше метод subscription возвращает объект, содержащий метод subscribe, используемый для обработки подписок, и метод unsubscribe, который обрабатывает отмены подписки.

Наконец, наш pub / sub class содержит метод publish, который принимает переменное количество аргументов и вызывает все функции, которые подписаны на указанное событие с этими аргументами, используя apply. Вы можете узнать больше о том, как apply работает, прочитав предыдущую статью из этой серии.

Преимущества шаблона публикации / подписки

Слабое разделение шаблона Pub / sub делает его пригодным для решения многих задач разработки программного обеспечения. Он хорошо масштабируется и хорошо подходит для распределенных архитектур, таких как микросервисы.

Pub / sub отлично подходит для создания уведомлений о событиях, распределенного кэширования, распределенного ведения журналов и систем с несколькими источниками данных.

Некоторые примеры реальных приложений, использующих шаблон pub / sub, - это Redis, Split, Twillo и Gutenberg, созданные Netflix.

Шаблон публикации / подписки против шаблона наблюдателя и привязки данных

Выше мы узнали, что основное различие между шаблоном pub / sub и наблюдателем заключается в том, что шаблон pub / sub предлагает полное отделение подписчиков от издателей. Однако в шаблоне наблюдателя наблюдатели или подписчики должны знать о предмете, также известном как наблюдаемые.

Кроме того, в шаблоне наблюдателя нет брокера, и наблюдаемые объекты сами отправляют уведомления.

Связывание данных - это общий термин. Вкратце, это просто означает, что «значение свойства X объекта Foo семантически привязано к значению свойства Y объекта Bar. Нет никаких предположений о том, как Foo узнает или получает изменения на объекте Bar.

Связывание данных может быть реализовано с использованием шаблона pub / sub или наблюдателя. И данные - это Publisher / Observable.

Заключение

Паттерны pub / sub и наблюдатель - это паттерны проектирования, с которыми должен быть знаком каждый разработчик.

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

SessionStack использует службы pub / sub для обработки всех полученных поведенческих данных из браузера в режиме реального времени. Во время приема данных SessionStack позволяет вам просматривать пользовательские сеансы в виде видео, позволяя точно увидеть, что произошло во время их путешествия.
Объединяя эту визуальную информацию со всеми техническими данными из браузера, такими как ошибки, трассировки стека, сетевые проблемы, данные отладки и т. д., вы можете легко понять проблемные области в вашем продукте и эффективно их решить.

Существует бесплатная пробная версия, если вы хотите попробовать SessionStack.

Если вы пропустили предыдущие главы серии, вы можете найти их здесь: