Decoupling Business Logic with Domain Events Using Guava EventBus

This article explains how to apply Domain‑Driven Design's domain events to separate reply handling from push notification logic, discusses the shortcomings of embedding side‑effects directly, compares Spring and Guava event mechanisms, and provides a custom Guava‑based publisher implementation with synchronous and asynchronous buses.

Programmer DD
Programmer DD
Programmer DD
Decoupling Business Logic with Domain Events Using Guava EventBus

Problem: Coupling side‑effects in business logic

A naive reply implementation mixes domain logic with side‑effects such as push notification:

void reply(long fromUserId, long toUserId, String content) {
    saveReply(fromUserId, toUserId, content);
    sendPush(toUserId, content);
}

The reply operation fails if the push fails, even though the core action succeeded.

Adding new concerns (e.g., reply counters) requires modifying the reply method, violating the Open‑Closed Principle.

Domain events as a decoupling mechanism

A domain event represents a fact that has occurred in the domain. After the core use‑case finishes, the event is published; interested components subscribe and handle their own concerns. This follows the publish‑subscribe (observer) pattern and keeps the core logic isolated.

Limitations of existing frameworks

Spring’s event system is synchronous, forcing publisher and subscriber to run in the same call stack.

Guava’s EventBus supports sync and async modes but requires the event type to be fixed at initialization, reducing flexibility.

Both frameworks make it difficult for subscribers to unregister, limiting dynamic subscription management.

Custom wrapper based on Guava EventBus

Define a DomainEventPublisher abstraction: identify() – unique identifier for the publisher. register(Object listener) – registers a subscriber. publish(T event) – synchronous publishing. asyncPublish(T event) – asynchronous publishing.

An abstract base class for domain events provides a timestamp and an abstract identify() method for distinguishing events.

Implementation example

public abstract class GuavaDomainEventPublisher implements DomainEventPublisher {
    private EventBus syncBus = new EventBus(identify());
    private EventBus asyncBus = new AsyncEventBus(identify(), Executors.newFixedThreadPool(1));

    @Override
    public void register(Object listener) {
        syncBus.register(listener);
        asyncBus.register(listener);
    }

    @Override
    public void publish(DomainEvent event) {
        syncBus.post(event);
    }

    @Override
    public void asyncPublish(DomainEvent event) {
        asyncBus.post(event);
    }
}

Two buses are created: syncBus for immediate, in‑process events and asyncBus for background processing. The async bus uses a single‑thread pool by default; the pool size can be reconfigured as needed.

Usage

Concrete publishers extend GuavaDomainEventPublisher and implement identify(). Subscribers annotate handler methods with Guava’s @Subscribe, eliminating custom unsubscribe logic.

Publishing a ReplyCreatedEvent after persisting a reply allows push‑notification logic, reply counters, audit logging, and other side‑effects to be handled independently, keeping the reply use‑case clean and adhering to DDD principles.

Key points

Domain events isolate core business logic and satisfy the Open‑Closed Principle.

The custom wrapper provides both synchronous and asynchronous publishing without hard‑coding event types.

Subscribers can be registered and unregistered dynamically, improving flexibility over standard Spring or Guava event mechanisms.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaDomain-Driven DesignGuavaEventBusDomain EventsPublish-Subscribe
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.