Observer
Define one-to-many dependency between objects
Overview
The Observer pattern defines a one-to-many dependency between objects. When one object (subject) changes state, all its dependents (observers) are notified and updated automatically.
This is the foundation of event-driven programming and is used extensively in UI frameworks.
Key Concepts
One-to-many relationship
Subject maintains list of observers
Observers subscribe/unsubscribe to subject
Subject notifies all observers on state change
Loose coupling between subject and observers
Code Example
1// Observer interface
2interface Observer {
3 void update(String stockSymbol, double price);
4}
5
6// Subject interface
7interface Subject {
8 void registerObserver(Observer observer);
9 void removeObserver(Observer observer);
10 void notifyObservers();
11}
12
13// Concrete Subject
14class StockMarket implements Subject {
15 private Map<String, Double> stocks = new HashMap<>();
16 private List<Observer> observers = new ArrayList<>();
17 private String lastUpdatedStock;
18
19 @Override
20 public void registerObserver(Observer observer) {
21 observers.add(observer);
22 }
23
24 @Override
25 public void removeObserver(Observer observer) {
26 observers.remove(observer);
27 }
28
29 @Override
30 public void notifyObservers() {
31 double price = stocks.get(lastUpdatedStock);
32 for (Observer observer : observers) {
33 observer.update(lastUpdatedStock, price);
34 }
35 }
36
37 public void setStockPrice(String symbol, double price) {
38 stocks.put(symbol, price);
39 lastUpdatedStock = symbol;
40 notifyObservers();
41 }
42}
43
44// Concrete Observers
45class StockAlert implements Observer {
46 private String name;
47 private Map<String, Double> watchList = new HashMap<>();
48
49 public StockAlert(String name) {
50 this.name = name;
51 }
52
53 public void addToWatchList(String symbol, double targetPrice) {
54 watchList.put(symbol, targetPrice);
55 }
56
57 @Override
58 public void update(String symbol, double price) {
59 if (watchList.containsKey(symbol)) {
60 double target = watchList.get(symbol);
61 if (price <= target) {
62 System.out.println(name + " ALERT: " + symbol +
63 " is now $" + price + " (target: $" + target + ")");
64 }
65 }
66 }
67}
68
69class StockDisplay implements Observer {
70 private String displayName;
71
72 public StockDisplay(String name) {
73 this.displayName = name;
74 }
75
76 @Override
77 public void update(String symbol, double price) {
78 System.out.println(displayName + " Display: " + symbol + " = $" + price);
79 }
80}
81
82// Usage
83public class Main {
84 public static void main(String[] args) {
85 StockMarket market = new StockMarket();
86
87 // Create observers
88 StockAlert investor1 = new StockAlert("John");
89 investor1.addToWatchList("AAPL", 150.00);
90
91 StockDisplay display = new StockDisplay("Main");
92
93 // Register observers
94 market.registerObserver(investor1);
95 market.registerObserver(display);
96
97 // Update stock prices - observers notified automatically
98 market.setStockPrice("AAPL", 175.00); // Above target
99 market.setStockPrice("AAPL", 145.00); // Below target - alert!
100 market.setStockPrice("GOOG", 2800.00);
101 }
102}StockMarket notifies all registered observers when stock prices change. Each observer decides how to respond.
When to Use
When changes in one object require updating others
Event handling systems
Loose coupling between components
Publish-subscribe systems
Real-World Example
- GUI event listeners (button clicks)
- Social media notifications
- Email subscriptions
- Model-View separation in MVC
- Real-time data feeds
💡 Interview Tips
Explain subject-observer relationship
Show stock market or notification example
Discuss push vs pull notification models
Mention Java's PropertyChangeListener
Connect to event-driven architecture