Observer
The problem
When a sold-out book is restocked, several things should happen: waitlisted customers get an email,
the storefront’s “notify me” subscribers get a text, the sales dashboard updates. If Inventory
calls the email service, the SMS service, and the dashboard directly, the stock system depends on
every notification channel – and grows a new dependency each time marketing adds one.
The pattern
Interested parties subscribe to the inventory; the inventory just announces the event to whoever is currently listening:
inventory.subscribe(emailAlerts);
inventory.subscribe(book -> dashboard.increment(book.isbn())); // lambdas work too
inventory.restock(book); // every subscriber is notified
Benefits
- Loose coupling – the subject knows the listener interface only; notification channels come and go without touching inventory code.
- Open-ended reactions – new behaviour (push notifications, analytics) is a new subscriber, not a change to the event source.
- Dynamic at runtime – subscribe and unsubscribe as customers opt in and out.
A note on modern practice
In-process, this is often spelled ApplicationEventPublisher (Spring) or an event bus; between
services it becomes messaging (Kafka, SQS). Same pattern, bigger arena.
Seen in the wild
Swing/JavaFX listeners, PropertyChangeListener, Spring’s ApplicationEvent +
@EventListener, java.util.concurrent.Flow (reactive streams).
Implementation
Inventory– the subject announcing restocks to subscribers.StockListener– the listener interface.EmailAlerts– a concrete subscriber.