Event based communication
Decouple your code using events
Image generated by AI
Introduction
Decoupling is a recommended approach for effective software development. One of the options we have is using events. Event based communication has various levels of abstraction. Event based communication at architecture level like an event driven architecture for micro-services. The other one I could think of is using a pub-sub approach at code level. In this blog we will try to understand how to use event based code to decouple your java classes.
Example
Let us take an example of JavaFX UI wherein you have a Header component having a Search input and Body component showing the search results as per the entered search text. Header amd Body JavaFX controller are separate but are shown on the same UI screen. They are siblings but not having an inheritance which we could have leveraged for message data passing from parent to child.
Classes
Below are the model classes for this simple demo. It is a basic representation to explain the concept we are not showing any JavaFX dependency here for brevity. It only contains core java classes for the use case.
package com.demos.eventdemos;
public class Header {
public void search(String text) {
System.out.println("Entered search text in header: " + text);
Event.SEARCH_BY_TEXT.dispatch(text);
}
}
package com.demos.eventdemos;
public class Body {
public Body() {
Event.SEARCH_BY_TEXT.addListener(this::getBySearchText);
}
public void getBySearchText(String text) {
System.out.println("Body fetching data by text: " + text);
}
}
package com.demos.eventdemos;
import java.util.function.Consumer;
public enum Event {
SEARCH_BY_TEXT;
private Consumer<String> listener;
public void addListener(Consumer<String> listener) {
this.listener = listener;
}
public void dispatch(String data) {
listener.accept(data);
}
}
package com.demos.eventdemos;
public class AppDemo {
public static void main(String[] args) {
Header header = new Header();
Body body = new Body();
header.search("Hello");
}
}
Sample output
Below is the sample output
Entered search text in header: Hello
Body fetching data by text: Hello
Points to be noted
Enum defines what events are triggered.
It currently shows a single listener since we have a one-to-one mapping but you can convert that to a collection of listeners. More about that in later blogs.
Event enum is a pub-sub broker facilitating the communication between publishers and subscribers.
Header and Body classes are not aware of each other one of the reason being the Event enum i.e. the broker and other reason is the java 8 lambdas as we only differentiated the subscriber as any consumer of text message.
Body class i.e. the subscriber has registered its handler method in the constructor so that during the app startup all the dependencies are met.
In the Demo class we can see that we are sending the text to the header and header is sending to Body. In the actual JavaFX controller the UI Textfield will be passing that value to the controller variable.
The code is readable when we are dispatching the events we are talking in terms as Event.<Event Name>.dispatch.
Summary
A decoupled code is maintainable and extensible. In this blog we took a simple use case with a single subscriber and simple event data. In the upcoming blogs I will be explaining how to handle the complexity of multiple publishers and subscribers which have different kind of event data and how to model that versatile event data.