Observer Pattern
Part of the Object Oriented Programming section of Coddy's Java journey — lesson 68 of 87.
The Observer Pattern is a behavioral design pattern that establishes a one-to-many relationship between objects. When one object (the subject) changes state, all its dependents (the observers) are automatically notified and updated. Think of it like a newsletter subscription—subscribers receive updates whenever new content is published.
The pattern involves two main components: a subject that maintains a list of observers and notifies them of changes, and observers that define an update method to respond to notifications:
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class NewsPublisher {
private List<Observer> subscribers = new ArrayList<>();
public void subscribe(Observer observer) {
subscribers.add(observer);
}
public void unsubscribe(Observer observer) {
subscribers.remove(observer);
}
public void publish(String news) {
for (Observer subscriber : subscribers) {
subscriber.update(news);
}
}
}
class EmailSubscriber implements Observer {
private String email;
public EmailSubscriber(String email) {
this.email = email;
}
public void update(String message) {
System.out.println("Email to " + email + ": " + message);
}
}When the publisher releases news, all subscribers are notified automatically:
NewsPublisher publisher = new NewsPublisher();
publisher.subscribe(new EmailSubscriber("alice@mail.com"));
publisher.subscribe(new EmailSubscriber("bob@mail.com"));
publisher.publish("Breaking news!");
// Output:
// Email to alice@mail.com: Breaking news!
// Email to bob@mail.com: Breaking news!The Observer Pattern promotes loose coupling—the subject doesn't need to know the concrete classes of its observers, only that they implement the Observer interface. This makes it easy to add new observer types without modifying the subject.
Challenge
EasyLet's build a stock price alert system using the Observer Pattern! You'll create a system where a stock ticker notifies multiple investors whenever the stock price changes, allowing each investor to react to price updates in their own way.
You'll organize your code across four files:
Observer.java: Define theObserverinterface that all investors will implement. It should declare a single methodupdate(String stockName, double price)that observers use to receive notifications about price changes.StockTicker.java: Create the subject class that maintains a list of observers and notifies them of price changes. YourStockTickershould have:A private String field for the stock name (set via constructor).
A private double field for the current price (initially 0).
A private list to store subscribed observers.
A
subscribe(Observer observer)method that adds an observer to the list.An
unsubscribe(Observer observer)method that removes an observer from the list.A
setPrice(double price)method that updates the price and then notifies all observers by calling theirupdatemethod with the stock name and new price.Investors.java: Create two different types of investors that implement theObserverinterface:DayTrader- has a private name field set via constructor. When updated, prints[name] received alert: [stockName] is now $[price] - Making quick trade!LongTermInvestor- has a private name field set via constructor. When updated, prints[name] received alert: [stockName] is now $[price] - Holding steady.Format the price with two decimal places.
Main.java: Bring your observer system together! You'll receive three inputs: the stock name (String), the first price update (double), and the second price update (double).Create a
StockTickerwith the given stock name. Create aDayTradernamed"Alice"and aLongTermInvestornamed"Bob", and subscribe both to the ticker.Set the price to the first input value (all observers get notified). Then unsubscribe Alice. Finally, set the price to the second input value (only Bob should be notified this time).
You will receive three inputs in order: stock name (String), first price (double), second price (double).
This challenge demonstrates the Observer Pattern's power: the StockTicker doesn't know anything about the specific investor types—it just knows they implement Observer. When you unsubscribe Alice, she stops receiving updates while Bob continues to be notified. This loose coupling makes it easy to add new investor types without changing the ticker!
Cheat sheet
The Observer Pattern is a behavioral design pattern that establishes a one-to-many relationship between objects. When one object (the subject) changes state, all its dependents (the observers) are automatically notified and updated.
The pattern involves two main components:
- Subject: Maintains a list of observers and notifies them of changes
- Observers: Define an update method to respond to notifications
Basic structure:
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void subscribe(Observer observer) {
observers.add(observer);
}
public void unsubscribe(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
class ConcreteObserver implements Observer {
public void update(String message) {
// React to notification
}
}Usage example:
Subject subject = new Subject();
subject.subscribe(new ConcreteObserver());
subject.notifyObservers("State changed!");
// All subscribed observers receive the updateThe Observer Pattern promotes loose coupling—the subject doesn't need to know the concrete classes of its observers, only that they implement the Observer interface. This makes it easy to add new observer types without modifying the subject.
Try it yourself
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Read inputs
String stockName = scanner.nextLine();
double firstPrice = scanner.nextDouble();
double secondPrice = scanner.nextDouble();
// TODO: Create a StockTicker with the given stock name
// TODO: Create a DayTrader named "Alice"
// TODO: Create a LongTermInvestor named "Bob"
// TODO: Subscribe both Alice and Bob to the ticker
// TODO: Set the price to firstPrice (both observers get notified)
// TODO: Unsubscribe Alice
// TODO: Set the price to secondPrice (only Bob gets notified)
scanner.close();
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsFields (Attributes)Constructor MethodConstructor OverloadingRecap - Simple Calculator4Inheritance
Basic Inheritance (extends)The super KeywordMethod Overriding (@Override)Constructor ChainingThe Object ClassSingle & Multilevel InheritWhy No Multi Class InheritRecap - Employee Hierarchy7Special Methods & Object Class
toString() Methodequals() and hashCode()clone() MethodcompareTo() and ComparableComparator InterfaceRecap - Custom Sorting2Access Modifiers & Encapsulate
Access Levels OverviewGetter and Setter MethodsInformation HidingThe final KeywordRecap - Bank Account Manager5Polymorphism
Method Overloading BasicsMethod Overriding (Run-Time)Upcasting and DowncastingThe instanceof OperatorAbstract Classes and MethodsRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceAggregation vs CompositionInner Nested & Anonymous ClassEnums and Enum MethodsRecords (Java 16+)Sealed Classes (Java 17+)11Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternBuilder PatternObserver PatternStrategy Pattern3Class Props & Static Member
Instance vs Static VariablesStatic MethodsStatic BlocksConstants (static final)Recap - Counter & Utility6Interfaces & Abstract Classes
Introduction to InterfacesImplementing InterfacesMulti Interface ImplemenDefault & Static in InterfaceAbstract Classes vs InterfacesFunctional InterfacesRecap - Payment System