mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 10:58:42 +00:00
docs: update data bus
This commit is contained in:
+30
-25
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: Data Bus
|
||||
category: Behavioral
|
||||
category: Messaging
|
||||
language: en
|
||||
tag:
|
||||
- Decoupling
|
||||
- Event-driven
|
||||
- Messaging
|
||||
- Publish/subscribe
|
||||
- Scalability
|
||||
---
|
||||
|
||||
## Also known as
|
||||
@@ -20,17 +21,19 @@ The Data Bus design pattern aims to provide a centralized communication channel
|
||||
|
||||
## Explanation
|
||||
|
||||
Real world example
|
||||
Real-world example
|
||||
|
||||
> Say you have an app that enables online bookings and participation of events. You want the app to send notifications such as event advertisements to everyone who is an ordinary member of the community or organisation holding the events. However, you do not want to send such notifications like advertisements to the event administrators or organisers, but you desire to send them and them only the time whenever a new advertisement is sent to all members of the community. The Data Bus enables you to selectively notify people of a community by type, whether it be ordinary community members or event administrators, by making their classes or components only accept messages of a certain type. Ultimately, there is no need for the components or classes of ordinary community members nor administrators to know anything about you in terms of the classes or components you are using to notify the entire community except for the need to know the type of the messages you are sending.
|
||||
> Consider a large airport as an analogous real-world example of the Data Bus design pattern. In an airport, various airlines, passengers, baggage handlers, and security personnel all need to communicate and share information. Instead of each entity communicating directly with every other entity, the airport uses a centralized announcement system (the Data Bus). Flight information, security alerts, and other critical updates are broadcast over this system, and each entity listens for the messages relevant to them. This setup allows the airport to decouple the communication process, ensuring that each entity only receives the information they need, while allowing the system to scale and integrate new entities without disrupting the existing ones.
|
||||
|
||||
In plain words
|
||||
|
||||
> Data Bus is a design pattern that is able to connect components of an application for communication simply and solely by the type of message or event that may be transferred.
|
||||
|
||||
Programmatic Example
|
||||
**Programmatic Example**
|
||||
|
||||
Translating the online events app example above, we firstly have our Member interface and its implementations composed of MessageCollectorMember (the ordinary community members) and StatusMember (the event administrators or organisers).
|
||||
Say you have an app that enables online bookings and participation in events. You want the app to send notifications, such as event advertisements, to all ordinary members of the community or organization holding the events. However, you do not want to send such advertisements to event administrators or organizers. Instead, you want to send them notifications about the timing of new advertisements sent to all members. The Data Bus enables you to selectively notify community members by type (ordinary members or event administrators) by making their classes or components only accept messages of a certain type. Thus, ordinary members and administrators do not need to know about each other or the specific classes or components used to notify the entire community, except for knowing the type of messages being sent.
|
||||
|
||||
In the online events app example above, we first define our `Member` interface and its implementations: `MessageCollectorMember` (ordinary community members) and `StatusMember` (event administrators or organizers).
|
||||
|
||||
```java
|
||||
public interface Member extends Consumer<DataType> {
|
||||
@@ -39,10 +42,10 @@ public interface Member extends Consumer<DataType> {
|
||||
}
|
||||
```
|
||||
|
||||
Then we have a data bus to subscribe someone to be a member or unsubscribe, and also to publish an event so to notify every member in the community.
|
||||
Next, we implement a data bus to subscribe or unsubscribe members and to publish events to notify all community members.
|
||||
|
||||
```java
|
||||
public class DataBus {
|
||||
public class DataBus {
|
||||
|
||||
private static final DataBus INSTANCE = new DataBus();
|
||||
|
||||
@@ -58,7 +61,6 @@ Then we have a data bus to subscribe someone to be a member or unsubscribe, and
|
||||
* @param member The member to register
|
||||
*/
|
||||
public void subscribe(final Member member) {
|
||||
|
||||
this.listeners.add(member);
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ Then we have a data bus to subscribe someone to be a member or unsubscribe, and
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish and event to all members.
|
||||
* Publish an event to all members.
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
@@ -85,9 +87,9 @@ Then we have a data bus to subscribe someone to be a member or unsubscribe, and
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, the accept method is applied for each member under the publish method.
|
||||
The `accept` method is applied to each member in the `publish` method.
|
||||
|
||||
Hence, as shown below, the accept method can be used to check the type of message to be published and successfully send/handle that message if the accept method has an instance for that message. Otherwise, the accept method cannot as is for the case of the MessageCollectorMember (the ordinary community members) when the type of message being sent is StartingData or StoppingData (information on the time whenever a new advertisement is sent to all members).
|
||||
For ordinary community members (`MessageCollectorMember`), the `accept` method can handle only `MessageData` type messages.
|
||||
|
||||
```java
|
||||
public class MessageCollectorMember implements Member {
|
||||
@@ -109,7 +111,7 @@ public class MessageCollectorMember implements Member {
|
||||
}
|
||||
```
|
||||
|
||||
However, the StatusMember(the event administrators or organisers) can accept such types of messages as
|
||||
For event administrators or organizers (`StatusMember`), the `accept` method can handle `StartingData` and `StoppingData` type messages.
|
||||
|
||||
```java
|
||||
public class StatusMember implements Member {
|
||||
@@ -120,6 +122,10 @@ public class StatusMember implements Member {
|
||||
|
||||
private LocalDateTime stopped;
|
||||
|
||||
public StatusMember(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(final DataType data) {
|
||||
if (data instanceof StartingData) {
|
||||
@@ -131,10 +137,10 @@ public class StatusMember implements Member {
|
||||
}
|
||||
```
|
||||
|
||||
Here is the App class to demonstrate the Data Bus pattern in action:
|
||||
Here is the `App` class to demonstrate the Data Bus pattern in action:
|
||||
|
||||
```java
|
||||
class App {
|
||||
```java
|
||||
class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
final var bus = DataBus.getInstance();
|
||||
@@ -146,21 +152,20 @@ Here is the App class to demonstrate the Data Bus pattern in action:
|
||||
bus.publish(StartingData.of(LocalDateTime.now()));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Thus, the data bus outputs as follows:
|
||||
|
||||
```
|
||||
//02:33:57.627 [main] INFO com.iluwatar.databus.members.StatusMember - Receiver 2 sees application started at 2022-10-26T02:33:57.613529100
|
||||
|
||||
//02:33:57.633 [main] INFO com.iluwatar.databus.members.StatusMember - Receiver 1 sees application started at 2022-10-26T02:33:57.613529100
|
||||
```
|
||||
|
||||
Evidently, due to MessageCollectorMembers only accepting messages of type MessageData and none of either StartingData nor StoppingData, the MessageCollectorMembers are prevented from seeing what the StatusMembers (the event administrators or organisers) are shown: information on the time whenever a new advertisement is sent to all members.
|
||||
When the data bus publishes a message, the output is as follows:
|
||||
|
||||
```
|
||||
02:33:57.627 [main] INFO com.iluwatar.databus.members.StatusMember - Receiver 2 sees application started at 2022-10-26T02:33:57.613529100
|
||||
02:33:57.633 [main] INFO com.iluwatar.databus.members.StatusMember - Receiver 1 sees application started at 2022-10-26T02:33:57.613529100
|
||||
```
|
||||
|
||||
As shown, `MessageCollectorMembers` only accept messages of type `MessageData`, so they do not see the `StartingData` or `StoppingData` messages, which are only visible to `StatusMember` (the event administrators or organizers). This selective message handling prevents ordinary community members from receiving administrative notifications.
|
||||
|
||||
## Class diagram
|
||||
|
||||

|
||||

|
||||
|
||||
## Applicability
|
||||
|
||||
|
||||
Reference in New Issue
Block a user