Observer vs Pub-Sub pattern

Какой из паттернов лучше Наблюдатель или Издатель-Подписчик?

Efim Sirotkin
Clean Code

--

Однажды, во время собеседования, мне задали вопрос: “Чем отличаются паттерны Observer (Наблюдатель) и Pub-Sub?

Я смекнул, что Pub-Sub означает Издатель-Подписчик, и тут же вспомнил “формулу”, из книги Head First Design Patterns:

Издатели + Подписчики = паттерн Наблюдатель.

“Он хочет обвести меня вокруг пальца. Сейчас я тебя сделаю”, — пронеслось в голове.

Улыбнувшись на все 32 я ответил: — Никакой разницы нет. Они похожи.”

Но интервьюер, улыбнувшись так, как будто прочитал мои мысли, ответил: — “Неправильно. Разница есть.”
Мое лицо выражало крайнее недоумение: “Что-о-о? Постойте! Что это значит?”

Где подвох? В чем я ошибся?

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

Прежде чем углубляться в различия, давайте сначала поговорим о паттернах Наблюдатель и Издатель-Подписчик.

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

Думаю, что многие со мной согласятся, если скажу, что паттерн проектирования Наблюдатель считается одним из самых простых паттернов. Я имею в виду, что когда вы впервые читаете о Наблюдателе то, в отличие от других паттернов, по крайней мере можете “прочувствовать” его концепцию.

“Наблюдатель — это паттерн проектирования, в котором объект, называемый subject, поддерживает группу зависимых от него объектов, называемых observers, и автоматически уведомляет их о любых изменениях состояния, вызывая, как правило, один из своих методов.” — определение из Википедии

Попробую объяснить попроще.

Предположим, вы ищете работу в качестве инженера-программиста и хотите работать в компании Banana Inc.

Итак, вы связались с их HR-ом и оставили ему свой контактный номер Он заверил вас, что как только появится подходящая вакансия, вас сразу же об этом известят. Кроме вас в компанию обратились еще несколько соискателей. Поэтому, при появлении вакансии, HR-ы сообщат о ней всем потенциальным кандидатам на работу. Если вы откликнитесь на их уведомление, возможно вас даже пригласят на собеседование.

Как это связано с паттерном проектирования Наблюдатель?

Компания Banana Inc. выступает в качестве Subject (Субъекта), который ведет список всех Observers (Наблюдателей) (кандидатов, таких как вы) и будет notify их об определенном event(вакансии).

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

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

Я не собираюсь «раздувать» эту статью с помощью примеров кода. В сети их предостаточно.

Паттерн проектирования Подписчик-Издатель

Согласен с тем фактом, что Subject в Наблюдателе похож на Publisher, а Observer также может быть связан с Subscriber.

Да, Subject уведомляет Observers так же, как Publisher обычно уведомляет своих подписчиков. Вот почему в большинстве книг или статей, посвященных паттернам проектирования, для объяснения паттерна проектирования Наблюдатель используют паттерн Подписчик-Издатель.

Паттерн Подписчик-Издатель — это еще один популярный паттерн проектирования, который концептуально очень похож на Наблюдателя.

Главное различие между этими двумя паттернами (Издатель-Подписчик и Наблюдатель) в следующем:

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

Это означает, что ни издатель, ни подписчик не знают о существовании друг друга.

Существует еще и третий компонент, называемый брокером (брокером сообщений или шиной событий), о котором знают и издатель, и подписчик. Он фильтрует все входящие сообщения и распределяет их.

Другими словами, Издатель-Подписчик — это паттерн, используемый для передачи сообщений между различными компонентами системы, которые ничего не знают о существовании друг друга.

Как брокер фильтрует все сообщения? На самом деле, существует несколько процессов для фильтрации сообщений. Наиболее популярными методами являются тематический и контентный.

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

Рис. Паттерн Подписчик-Издатель (рисунок взят с блог MSDN)

В двух словах, основное различие между этими двумя паттернами можно описать следующим образом:

В этом есть здравый смысл?

Давайте кратко подытожим все различия:

  • В паттерне Наблюдатель наблюдателям известно о наличии Subject. Subject ведет учет Observers. В то время как в паттерне Издатель-Подписчик издателям и подписчикам не нужно знать о существовании друг друга. Для коммуникаций между собой они используют брокера или очередь сообщений.
  • Компоненты паттерна Издатель-Подписчик, в отличие от паттерна Наблюдатель, имеют слабые связи.
  • Паттерн Наблюдатель в основном реализуется синхронно, т. е., когда происходит событие, Subject вызывает соответствующий метод всех своих наблюдателей. Паттерн Издатель-Подписчик в основном реализуется асинхронно (используется очередь сообщений).
  • Паттерн Наблюдатель должен быть реализовыван в адресном пространстве одного приложения, в то время как Издатель-Подписчик является кросс-программным паттерном.

Несмотря на различия между этими двумя паттернами, кто-то может сказать (и частично будет прав), что Издатель-Подписчик — это всего лишь разновидность Наблюдателя, из-за концептуального сходства между ними. Эти паттерны очень похожи, не так ли?

Ну что? На сегодня у меня все. Надеюсь, идея вам понятна. Благодарю за прочтение этой статьи. Если вы заметили ошибки или если необходимо внести какие-либо исправления — сообщите мне об этом, пожалуйста. Зараннее благодарю.

Translated: medium

--

--