Observer helps when one object’s state change should notify interested listeners without hard-wiring every dependent relationship.
Define a one-to-many dependency so when one object changes state, all its dependents are notified and updated automatically.
What the pattern is trying to do
Define a one-to-many dependency so when one object changes state, all its dependents are notified and updated automatically.
What force creates the need
Many interested parties need notification when something happens, but direct coupling between source and every dependent makes the design brittle.
How the pattern responds
Let observers subscribe to a subject so notifications can fan out through a stable contract.
How the moving parts fit together
A subject keeps a list of observers and broadcasts events or updates through a shared callback interface.
Java example in the Order Management domain
package org.javaomnibus.ecommerce.gof.behavioral;
public interface OrderObserver {
void onOrderConfirmed(Order order);
}
public final class OrderConfirmedPublisher {
private final java.util.List observers = new java.util.ArrayList<>();
public void register(OrderObserver observer) {
observers.add(observer);
}
public void publish(Order order) {
for (OrderObserver observer : observers) {
observer.onOrderConfirmed(order);
}
}
}
Step by step
- Publishers do not need deep knowledge of each observer implementation.
- Observers can be added or removed with less coupling to the source.
- This fits notification-style relationships more than central orchestration.
- Observer is often the gateway into event-driven design thinking.
Where this pattern helps
- When many listeners react to one event source
- When notification relationships should stay decoupled and extensible
When a simpler design is better
- When the source needs fine-grained control over the entire workflow
- When event fan-out would make behavior too implicit or difficult to trace
What this pattern costs
- Event-driven updates can make execution flow less explicit
- Ordering, retries, and failure handling require careful design as the system grows
How this fits today
Observer remains deeply relevant in Java for domain events, UI listeners, integration hooks, and event-driven processing models.
Where teams get it wrong
Using Observer when the business flow really needs centralized coordination can create hidden logic scattered across listeners.