The Observer Pattern

OOP · lesson 28 of 43 · 3 min read

How one object tells many listeners that something happened without knowing who they are.

Open this lesson in the learning hub

Key points

  • The subject keeps a list of listeners and calls them all when something happens. It never names them.
  • That is how you add email, metrics and a warehouse hook without touching the class that places orders.
  • In modern Java a listener is usually a Consumer or a small interface, registered with a lambda.
  • Listeners run on the caller thread by default, so one slow listener slows the whole publish. Hand off if that matters.
  • A listener that throws will stop the rest unless you catch per listener. Decide which behaviour you want.
  • Remember to unsubscribe. A listener list is a strong reference and it is a very common source of leaks.

Example

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Main {
    // The subject knows only that somebody wants to hear about this.
    static class OrderBook {
        private final List<Consumer<String>> listeners = new ArrayList<>();

        void onPlaced(Consumer<String> listener) { listeners.add(listener); }

        void place(String id) {
            System.out.println("order " + id + " placed");
            for (Consumer<String> listener : listeners) {
                listener.accept(id);                   // publish to every subscriber
            }
        }
    }

    public static void main(String[] args) {
        OrderBook orders = new OrderBook();
        orders.onPlaced(id -> System.out.println("   email     : receipt for " + id));
        orders.onPlaced(id -> System.out.println("   warehouse : pick " + id));
        orders.onPlaced(id -> System.out.println("   metrics   : counted " + id));

        orders.place("A-1");
        orders.place("A-2");

        System.out.println("OrderBook never mentions email, warehouse or metrics");
    }
}

Publish to a list of listeners and the subject stops depending on its audience.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the OOP course, and every lesson in it is listed on the OOP contents page.