Observer Design Pattern: Implementation in Java
The Observer design pattern is a behavioral design pattern, used to create a one-to-many dependency between objects so that when one object (the subject) changes its state, all its dependents (observers) are notified and updated automatically. In this blog post, we will delve into the Observer design pattern, explore its components, and implement Stock Market Monitoring.
Components of the Observer Design Pattern
- Subject: The subject maintains a list of observers and notifies them of state changes.
- Observer: The observer interface defines the contract for concrete observer classes.
- ConcreteSubject: A class that implements the subject interface and manages the observers.
- ConcreteObserver: A class that implements the observer interface and receives notifications.
Implementing Observer Design Pattern: Stock Market Monitoring
Suppose we want to create a stock market monitoring system where investors can subscribe to receive stock price updates for specific companies. Let’s implement this using the Observer pattern.
Step 1: Observer Interface
public interface StockObserver {
void update(String stockSymbol, double stockPrice);
}
Step 2: Create the ConcreteObserver class
public class Investor implements StockObserver {
private String name;
public Investor(String name) {
this.name = name;
}
@Override
public void update(String stockSymbol, double stockPrice) {
System.out.println(name + " received an update for " + stockSymbol + ": $" + stockPrice);
}
}
Step 3: Subject Interface
public interface StockMarket {
void registerObserver(StockObserver observer);
void removeObserver(StockObserver observer);
void notifyObservers(String stockSymbol, double stockPrice);
}
Step 4: ConcreteSubject class
import java.util.ArrayList;
import java.util.List;
public class StockMarketImpl implements StockMarket {
private List<StockObserver> observers = new ArrayList<>();
@Override
public void registerObserver(StockObserver observer) {
observers.add(observer);
}
@Override
public void removeObserver(StockObserver observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String stockSymbol, double stockPrice) {
for (StockObserver observer : observers) {
observer.update(stockSymbol, stockPrice);
}
}
// Simulate stock price changes
public void setStockPrice(String stockSymbol, double stockPrice) {
notifyObservers(stockSymbol, stockPrice);
}
}
Step 5: Make It Happen
public class Main {
public static void main(String[] args) {
StockMarket stockMarket = new StockMarketImpl();
StockObserver investor1 = new Investor("Alice");
StockObserver investor2 = new Investor("Bob");
stockMarket.registerObserver(investor1);
stockMarket.registerObserver(investor2);
stockMarket.setStockPrice("INFY", 1250.0); // Both investors receive updates
stockMarket.setStockPrice("TCS", 2500.0); // Both investors receive updates
stockMarket.removeObserver(investor1);
stockMarket.setStockPrice("WIPRO", 700.0); // Only investor2 receives the update
}
}
Conclusion
In the above example, we created a stock market monitoring system where investors receive updates when stock prices change. The pattern promotes flexibility and maintainability by allowing objects to communicate without being tightly coupled. You can apply this pattern in various scenarios, making your code more robust and adaptable to changing requirements.