Подтвердить что ты не робот

Почему люди используют шины сообщений/событий в своем коде?

Я думаю, что вы слышали о шинах сообщений/событий, это единственное место, когда все события в потоке системы. Подобные архитектуры находятся в компьютерных материнских платах и ​​сетях LAN. Это хороший подход для материнских плат и сетей, поскольку он уменьшает количество проводов, но хорошо ли это для разработки программного обеспечения? У нас нет таких ограничений, как электроника.

Простейшая реализация шины сообщений/событийной шины может быть такой:

class EventBus {
    void addListener(EventBusListener l}{...}
    void fireEvent(Event e) {...}
}

События проводки выполняются с помощью bus.fireEvent(событие), принимающие сообщения включаются bus.addListener(слушателем). Такие архитектуры иногда используются для разработки программного обеспечения, например MVP4G реализует аналогичную шину сообщений для GWT.

Активные проекты:

Бездействующие/мертвые проекты:

Это просто популярный шаблон Observer (Listener), сделанный "глобально" - каждый объект в системе может прослушивать каждое сообщение, и я думаю, что это плохо, он нарушает принцип инкапсуляции (каждый объект знает обо всем) и принцип единой ответственности (например, когда какой-либо объект нуждается в сообщении нового типа, частоту передачи часто необходимо изменить, например, для добавления нового класса Listener или нового метода в классе Listener).

По этим причинам, я думаю, что для большинства программ, шаблон Observer лучше, чем шина событий. Что вы думаете о шине событий, действительно ли это имеет смысл для типичных приложений?

EDIT: Я не говорю о "больших" корпоративных решениях, таких как ESB, - они могут быть полезны (что больше ESB предлагает гораздо больше, чем просто шина событий). Я прошу о полезности использования шины сообщений в "регулярном" Java-коде для соединения "объект-объект" - некоторые люди делают это, проверяют ссылки выше. Диспетчер событий, вероятно, является лучшим решением для телефонной или телефонной связи или связи между компьютером и компьютером, поскольку каждый телефон (или компьютер) в сети обычно может разговаривать друг с другом, а шина уменьшает количество проводов. Но объекты редко общаются друг с другом - сколько соавторов может иметь один объект - 3, 5?

4b9b3361

Ответ 1

Некоторым нравится это, потому что это воплощение Фасадное изображение или Посредник. Он централизует сквозные мероприятия, такие как ведение журнала, предупреждение, мониторинг, безопасность и т.д.

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

Ответ 2

Я рассматриваю возможность использования In Event Event Bus для моего обычного Java-кода, и мое обоснование выглядит следующим образом

Каждый объект в системе может прослушивать каждое сообщение, и я думаю, что это Плохо, он нарушает принцип инкапсуляции (каждый объект знает о все)

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

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

Я полностью не согласен с

Часто необходимо изменить частоту шины событий

Шина событий никогда не изменяется

Я согласен с

add a new Listener class or a new method in the Listener class

Как это сломает SRP?, я могу иметь BookEventListener, который подписывается на все события, относящиеся к моей книге Entity, и да, я могу добавлять методы к этому классу, но этот класс является сплоченным...

Почему я планирую использовать его? Это помогает мне моделировать "когда" моего домена....

Обычно мы слышим что-то вроде отправки почты , когда книга приобретается

запишем

book.purchase();
sendEmail()

Затем нам сообщают, что при покупке книги мы берем журнал аудита, переходим к приведенному выше фрагменту

book.purchase();
sendEmail();
**auditBook();**

Прямо там OCP нарушена

Предпочитаю

book.purchase();
EventBus.raiseEvent(bookPurchasedEvent);

Затем продолжайте добавлять обработчики по мере необходимости. Open for Extension Closed for Modification.

Спасибо

Ответ 3

Я использую его в JavaScript. Могут быть так много различных виджетов, что все нужно делать какое-то действие всякий раз, когда что-то происходит - нет реальной иерархии владения объектами. Вместо того, чтобы передавать ссылки каждого объекта на каждый объект или просто делать каждый объект глобальным, когда что-то значимое происходит внутри конкретного виджета, я могу просто опубликовать "/thisWidget/somethingHappened" - вместо заполнения этого виджета всеми видами кода к API других виджетов. У меня есть один класс, который содержит все "проводки" или "плунгирование", как им нравится называть его в Java Spring. Этот класс содержит ссылки на все мои виджеты и содержит весь код для того, что происходит после каждого события.

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

Ответ 4

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

По этим причинам я считаю, что для большинство программного обеспечения, шаблон Observer лучше, чем автобус событий. Что ты думать о автобусе событий, делает ли это любой хороший смысл для типичных приложения?

.. но, учитывая ваш пример, они одинаковы. Это заставляет задуматься, если вы когда-либо использовали что-то вроде Enterprise Service Bus. На базовом уровне ESB логически делает то же самое, что и шаблон наблюдателя, но коммерческие продукты добавляют намного больше. Это как автобус на стероидах. Они представляют собой сложные программные продукты и предлагают:

Сообщение о доставке
Генерируйте события, слушая различные конечные точки. Конечной точкой может быть слушатель (например, HTTP-сервер), система обмена сообщениями (например, JMS), база данных или почти все, что вы хотите.

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

Трансформация сообщений
Преобразует ваше сообщение в другой формат, это может быть так же просто, как от XML до JSON или от строки в таблице базы данных до HTTP-запроса. Преобразование может происходить в самих данных, например, в форматах даты замены.

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

.. и много, много больше. Когда вы начинаете изучать детали, вы действительно можете начать понимать, почему люди используют эти вещи.

Ответ 5

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

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

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

Итак, главный вопрос здесь - желаемый уровень развязки компонентов приложений.

Некоторые рекомендации об этом:

Ответ 6

Хорошей аналогией является телефонная станция, где каждый телефон может набирать все остальные трубки. Скомпрометированный телефон может настраиваться на другие разговоры. Программные управляющие потоки, такие как провода (циклическая сложность какая-либо!) Это похоже на требование наличия соединения/физической среды между двумя конечными точками. Это So для N телефонов вместо того, чтобы иметь NC2 (комбинаторная логика) для каждой новой трубки, мы склонны получать N потоков.

Сокращение сложности подразумевает понятный код. Давайте начнем с выдающихся точек, которые вы выделили: 1. Глобальное знание 2. Интрузивные модификации.

Глобальное знание: рассмотрите событие сообщения как конверт. С точки зрения обработчика/отправителя события нет данных, которые отображаются, он видит конверт (если только производный класс не пытается провести некоторую проверку с использованием проверок "instanceof" ). В хорошем дизайне ООП это никогда не произойдет.

Интрузивные модификации: вместо того, чтобы иметь подход к конкретному событию, можно использовать глобальный подход обработки событий. Таким образом, у нас есть глобальный тип события (на котором данные копируются и сбрасываются). Это похоже на модель PropertyBeanSupport в Java. При использовании одного типа событий мы должны иметь один тип отправителя и слушателя. Это означает, что вам не нужно изменять шины/слушатели каждый раз, когда вы видите что-то новое. Уродливое нисходящее литье может быть очищено с помощью шаблона адаптера (пожалуйста, не начинайте этот другой уровень цитаты перенаправления!). Программисты могут писать сборку на любом языке. Поэтому потребность в здравом рассудке и умности не может быть заменена. Все, что я хочу сказать, это эффективный инструмент.

Реальные приемники событий могут легко использовать слушателей (состав/прокси). В такой базе кода Java слушатели будут выглядеть как самостоятельные внутренние декларации классов (при этом в некоторых IDE помечено предупреждение о неиспользовании). Это зависит от двух игроков на пляже, играющих в мяч, игроки не реагируют, пока не видят мяч.

'@duffymo' указывает еще один интересный аспект: "Единая точка отказа". Это может/может теоретически воздействовать на любой объект, находящийся в памяти (ОЗУ), а не специфический для MessageHandlers.

Ответ 7

В качестве практического примера наше приложение синхронизируется с веб-службой каждые x минут, и если какие-либо новые данные получены, нам необходимо обновить графический интерфейс. Теперь, поскольку SyncAdapter работает в фоновом потоке, вы не можете просто указывать на текстовое представление и изменять его свойства, вы должны пузырить событие. И единственный способ убедиться, что вы поймаете это событие, - это если у вас есть общий (статический, одиночный) объект, передающий это событие для подписчиков.