Why do people use message / event buses in their code?

I think that you have heard about message / event buses, this is the only place where all events are in the system thread. Similar architectures are found in computer motherboards and LAN networks. This is a good approach for motherboards and networks as it reduces the number of wires, but is it good for software development? We have no such restrictions as electronics.

A simple implementation of a message / event bus may be:

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

Posting events are executed using bus.fireEvent (event), receiving messages are enabled by bus.addListener (listener). Such architectures are sometimes used for software development, for example MVP4G implements a similar message bus for GWT.

Active projects:

Inactive / Dead Projects:

It’s just a popular Observer (Listener) template made “globally” - every object in the system can listen to every message, and I think that this is bad, it violates the principle of encapsulation (every object knows everything) and the principle of uniform responsibility (for example, when an object needs a message of a new type, the transmission frequency often needs to be changed, for example, to add a new Listener class or a new method in the Listener class).

For these reasons, I think that for most programs, the Observer pattern is better than the event bus. What do you think of the event bus, does it really make sense for typical applications?

EDIT: I'm not talking about "big" enterprise solutions like ESBs - they can be useful (which is more ESB offers much more than just an event bus). I ask about the usefulness of using the message bus in "regular" Java code to connect an "object-object" - some people do this, check the links above. Event manager is probably the best solution for telephone or telephone communications, or communications between a computer and a computer, since each telephone (or computer) on the network can usually talk to each other, and the bus reduces the number of wires. But objects rarely communicate with each other - how many co-authors can one object have - 3, 5?

+60
java design event-handling events design-patterns
Oct 21 '10 at 12:25
source share
7 answers

Some people like this because it is an embodiment of the Facade Image or Mediator . It centralizes cross-cutting activities such as logging, warning, monitoring, security, etc.

Some people don't like it, because it's often a singleton point of failure. Everyone should know about this.

+26
Oct 21 2018-10-21
source share

I am considering using In Event Event Bus for my regular Java code, and my rationale is as follows

Every object in the system can listen to every message, and I think it is Bad, it violates the principle of encapsulation (every object knows everything)

I'm not sure if this is true, for this class I have to register on the event bus, similar to the observer pattern. As soon as the class is registered on the event bus, only methods that have the appropriate signature and annotation are notified.

and the principle of common responsibility (for example, when an object needs a new type of message, the frequency of the event often needs to be changed, for example, add a new Listener class or a new method in the Listener class).

I totally disagree with

Often you need to change the frequency of the event bus

Event bus never changes

I agree with

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

How does this break SRP ?, I can have a BookEventListener that subscribes to all events related to my Entity book, and yes, I can add methods to this class, but this class is cohesive ...

Why am I planning to use it? This helps me model the "when" of my domain ....

Usually we hear something like sending mail when a book is purchased

we write

 book.purchase(); sendEmail() 

Then we are informed that when buying a book we take an audit trail, go to the fragment above

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

Right there OCP is broken

I prefer

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

Then continue to add handlers as needed. Open for Extension Closed for Modification.

thank

+66
Jan 24 '12 at 9:28
source share

I use it in JavaScript. There can be so many different widgets that everyone needs to do some action whenever something happens - there is no real hierarchy of ownership of objects. Instead of passing links of every object to every object or just making every object global when something significant happens inside a particular widget, I can simply post "/ thisWidget / somethingHappened" - instead of filling this widget with all kinds of code to the API of other widgets . I have one class that contains all the "postings" or "plunging" as they like to call it in Java Spring. This class contains links to all my widgets and contains all the code for what happens after each event.

It is centralized, easy to access and maintain, and if one thing changes or I want a new process to occur at a specific event, I do not need to search through each separate class / object / widget to try to find where something is being processed. I can just go to my class “operator” - the one that processes all the “postings” when a particular event occurs, and see all the consequences of this event. In this system, each individual widget is fully API agnostic of other widgets. He just publishes what happened to him or what he does.

+16
Oct 21 '10 at 15:01
source share

I am having trouble understanding what you are really asking in your question. You give an example of a simple event bus, which is actually just Observable with a different name, and then you say:

For these reasons, I believe that for most software, an Observer pattern is better than an event bus. What do you think of the event bus, does that make any good sense for a typical application?

.. but, given your example, they are the same. It makes you wonder if you have ever used something like the Enterprise Service Bus. At a basic level, an ESB logically does the same thing as an observer pattern, but commercial products add a lot more. It's like a bus on steroids. They are complex software products and offer:

Delivery Message
Generate events by listening to various endpoints. The endpoint can be a listener (e.g., an HTTP server), a messaging system (e.g., JMS), a database, or just about anything you want.

Message routing
Take your event and send it to one / many endpoints. Routing can be pretty smart, a bus can route a message depending on the type of message, message content, or any other criteria. Routing can be intelligent and dynamic.

Message transformation
Converts your message to another format, it can be as simple as from XML to JSON or from a row in a database table to an HTTP request. Conversion can occur in the data itself, for example, in replacement date formats.

Data enrichment
Adds or modifies data in your message by invoking services along the way. For example, if the message contains a zip code, the bus can use the zip code search service to add it to the address data.

.. and many, many more. When you begin to learn the details, you can really begin to understand why people use these things.

+14
Oct 21 2018-10-10
source share

Because it can be an important step in decoupling application modules from service based on architecture .

So, in your case, if you do not intend to separate the modules of your application from isolated services, then the native implementation of the Observer template will make it a simpler solution.

But if you want to build, say, the architecture of microservices , the event bus will allow you to get the advantages of this style of architecture so that, for example, you can update and deploy only part of your application does not affect others, because they are simply connected via the event-bus.

So, the main question here is the desired level of decoupling of application components.

Some recommendations about this:

+4
Sep 22 '16 at 17:40
source share

A good analogy is a telephone exchange, where each telephone can dial all the other handsets. A compromised phone can tune in to other conversations. Software control flows, such as wires (some cyclic complexity!) This is similar to requiring a connection / physical medium between two endpoints. This is So for N phones, instead of having NC2 (combinatorial logic) for each new handset, we tend to get N threads.

Reducing complexity implies clear code. Let's start with the outstanding points that you have identified: 1. Global knowledge 2. Intrusive modifications.

Global knowledge: view the message event as an envelope. From the point of view of the event handler / sender, there is no data that is displayed, it sees the envelope (unless the derived class is trying to do some validation using the "instanceof" checks). In a good OOP design, this will never happen.

Intrusive modifications: instead of having a specific event approach, you can use a global event handling approach. Thus, we have a global type of event (on which data is copied and dumped). This is similar to the Java PropertyBeanSupport model. When using the same type of events, we must have one type of sender and listener. This means that you do not need to change buses / listeners every time you see something new. Ugly top-down casting can be cleaned with an adapter pattern (please don't start this other level of redirect quote!). Programmers can write an assembly in any language. Therefore, the need for common sense and intelligence cannot be replaced. All I want to say is an effective tool.

Real event receivers can easily use listeners (composition / proxies). In such a base of Java code, listeners will look like independent internal class declarations (at the same time, a warning about non-use is marked in some IDEs). It depends on the two players on the beach playing the ball, the players do not react until they see the ball.

'@duffymo' points out another interesting aspect: "Single point of failure." This can / can theoretically affect any object in memory (RAM), and not specific to MessageHandlers.

+2
Oct 21 2018-10-21
source share

As a practical example, our application is synchronized with the web service every x minutes, and if any new data is received, we need to update the graphical interface. Now, since the SyncAdapter is running in the background thread, you cannot just point to the text view and change its properties, you must bubble the event. And the only way to make sure that you catch this event is if you have a common (static, single) object that passes this event to subscribers.

+1
Jan 10 '17 at 12:23
source share



All Articles