Observer Pattern
Created on: Sep 23, 2024
There are many notifications in this digital world. We don't need every notification so we subscribe to a particular notification. Suppose we want to know the stock price change of a company say Reliance, we can subscribe to the price change of Reliance stock and we get the update regularly. This can be easily designed using observer pattern.
The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.
The pattern decouples the subject from the observers, meaning the subject doesn’t need to know any details about the observers—it simply notifies them of changes.
There are two key participants in this pattern.
- Subject: It maintains a list of observers and sends notifications when there a state change happens.
- Observer: It gets notified when there is a state change.
Steps for Implementing Observer Pattern:
- Subject Interface: This defines the methods to register, remove, and notify observers.
- Concrete Subject: This is the class that holds the state and notifies observers when a state change happens.
- Observer Interface: This defines the method update(), which will be called by the subject to notify the observer.
- Concrete Observer: The classes that implement the Observer interface and respond to changes in the subject.
Below is the high-level code for the above implementation.
public interface StockMarket { public void registerObserver(Observer observer); public void unregisterObserver(Observer observer); public void notifyPriceChange(String stockSymbol, double price); } public class StockMarketImpl implements StockMarket{ private List<Observer> observerList = new ArrayList<>(); @Override public void registerObserver(Observer observer) { this.observerList.add(observer); } @Override public void unregisterObserver(Observer observer) { this.observerList.remove(observer); } @Override public void notifyPriceChange(String stockSymbol, double price) { this.observerList.forEach(observer -> observer.notifyPriceChange(stockSymbol, price)); } public void setStockPrice(String stockSymbol, double price){ notifyPriceChange(stockSymbol, price); } } public interface Observer { public void notifyPriceChange(String stockSymbol, double price); } public class Invester implements Observer{ private String user; public Invester(String user) { this.user = user; } @Override public void notifyPriceChange(String stockSymbol, double price) { System.out.println("Current price of stock " + stockSymbol +" is: "+price); } }
In the above code, StockMarket is responsible for subscribing events due to changes in the price of a particular stock and Invester is one which subscribes to the change in price of that particular stock.
Run the following code.
public class StockmarketApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(StockmarketApplication.class, args); } @Override public void run(String... args) throws Exception { StockMarket stockMarket = new StockMarketImpl(); Observer investor1 = new Invester("u1"); Observer investor2 = new Invester("u2"); stockMarket.registerObserver(investor1); stockMarket.registerObserver(investor2); stockMarket.notifyPriceChange("INFY", 1888.15); stockMarket.notifyPriceChange("Reliance", 2990); } }
Current price of stock INFY is: 1888.15 Current price of stock INFY is: 1888.15 Current price of stock Reliance is: 2990.0 Current price of stock Reliance is: 2990.0
Check out the whole code in github.
You can try similar situation in a weather update. There is a weather app where many users can subscribe to changes in temperature. Write low-level code to notify the temperature change to each user. Find the answer here.
