Observer Design Pattern Explained With Java Sample

Introduction

 
What is an Observer Design Pattern?
 
The Observer Design Pattern is a Behavioral Pattern used to notify all the objects that are registered/attached/added to the same type of observer.
 
Why use the Observer Design Pattern?
 
When there is a requirement of "Single object change in its state/behavior/Value needs to notify all other objects which are observing the same object".
 
Basically, a single object should notify multiple objects of the same observer type. It's the relation of one object to many others.
 
Players in this pattern:
  • Subject: Provides a contract to add/remove observers
  • ConcreteSubject: Implements a contract defined by Subject
  • Observer: Provides a contract for updating objects when there is a change in the subject state/behavior/Value
  • ConcreteObserver: Implements a contract defined by Observer
Problem definition
 
Design a software solution for a wholesale pen seller. This wholesale pen seller will sell pens to shops. When there is a change in pen price per market demand, it should automatically notify the change in pen price to all shops.
 
The players are,
  • Subject – PenSubject
  • ConcreteSubject – Pen
  • Observer – ShopObserver
  • ConcreteObserver – Shop
Below is the PenSubject interface which will define contact for ConcreteSubjects 
  1. public interface PenSubject {  
  2.     void add(ShopObserver shop);  
  3.     void remove(ShopObserver shop);  
  4.     void notifyObservers();  
  5. }  
Below is the Pen class which implements PenSubject Interafce to add/remove Observers and call Notify, which will invoke when there is a change in pen price
  1. import java.util.ArrayList;  
  2.   
  3. public class Pen implements  PenSubject {  
  4.   
  5.     private double _penPrize;  
  6.   
  7.     public Pen(double penPrize)  
  8.     {  
  9.         _penPrize = penPrize;  
  10.     }  
  11.   
  12.     public double getPrize() { return this._penPrize; }  
  13.     public void setPrize(double penPrize) {  
  14.         if(this._penPrize!=penPrize) {  
  15.             this._penPrize = penPrize;  
  16.             this.notifyObservers();  
  17.         }  
  18.     }  
  19.   
  20.     private ArrayList<com.sample.ShopObserver>  shops = new ArrayList<>();  
  21.   
  22.     @Override  
  23.     public void add(ShopObserver shop) {  
  24.         shops.add(shop);  
  25.     }  
  26.   
  27.     @Override  
  28.     public void remove(ShopObserver shop) {  
  29.         shops.remove(shop);  
  30.     }  
  31.   
  32.     @Override  
  33.     public void notifyObservers() {  
  34.        shops.forEach(a->a.update(this));  
  35.        System.out.println("----------------------------------------------------------");  
  36.     }  
  37. }  
Below is the ShopObserver (Observer) interface which defines a contract for ConcreteObserver (i.e. in our case Shop)
  1. public interface ShopObserver {  
  2.     void update(Pen pen);  
  3. }  
Below is the Shop class which implements ShopObserver to update the Subject object
  1. public class Shop implements ShopObserver {  
  2.   
  3.     private String _shopName;  
  4.   
  5.     public Shop(String shopName)  
  6.     {  
  7.         _shopName = shopName;  
  8.     }  
  9.   
  10.     @Override  
  11.     public void update(Pen pen) {  
  12.         System.out.println("pen prize changed to " +  pen.getPrize() + " in " + _shopName);  
  13.     }  
  14. }  
We will see the execution and the result now 
  1. public class Main {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Pen pen = new Pen(10);  
  5.         pen.add(new Shop("Shop1"));  
  6.         pen.add(new Shop("Shop2"));  
  7.         pen.add(new Shop("Shop3"));  
  8.   
  9.         pen.setPrize(20);  
  10.         pen.setPrize(25);  
  11.         pen.setPrize(30);  
  12.     }  
  13. }  
Below is the result screenshot. In the result, we can see that change in pen price value has notified all shops
 
 

Summary

 
In this article, we have learned through code example what Observer design pattern is, as well as why and where to use it.