Observer pattern is one of the behavioral design patterns used in object oriented world of programming.
Definition – Observer pattern defines a one-to-many relationship between objects. When state of one object changes, all the dependent objects are notified and updated.
There is a Subject interface and a ConcreteSubject that implements the Subject interface. There is an Observer interface and multiple observers implementing that interface. Observers use the Subject interface to register and unregister and also to get notified about the changes. Observer interface generally has one function that is called by the Subject whenever there is a state change.
One way to visualize this is the newspaper subscription in the real world. As soon as a newspaper is published, all the subscribers get the new copy.
In java, common example of observer pattern are Observer interface, EventListeners in awt and swing, Observable, JMS etc.
Best to use an example to understand this pattern.
Usecase – Let’s say there is a pantry containing items. And there are different shopping lists based on different stores we visit. As soon as any item in pantry finishes we want to add that item to all the shopping lists.
Pantry is our subject. KitchenPantry is concrete subject implementing the Pantry interface. SuperStoreList is our observer interface. CostcoList and WalmartList are our observer. Both observers can register using the attach method and deregister using the detach method. As soon as the item is removed from KitchenPantry, it will be added both the observer’s lists using the update method. KitchenPantry will use notify to call that update method.
public interface Pantry
{
public void attach(SuperStoreList list);
public void detach(SuperStoreList list);
public void notify();
}
public interface SuperStoreList
{
public void update(String item);
}
public class KitchenPantry implements Pantry
{
private List<SuperStoreList> superStores;
private String item;
public KitchenPantry()
{
superStores = new ArrayList<SuperStoreList>();
}
public void attach(SuperStoreList list)
{
superStores.add(list);
}
public void attach(SuperStoreList list)
{
superStores.remove(list);
}
public void notify(String item)
{
for(SuperStoreList list: superStores)
{
list.update(item);
}
}
public void setItem(String item)
{
this.item = item;
itemAdded();
}
public void itemAdded()
{
notify(item);
}
public String getItem()
{
return this.item;
}
}
public class CostcoList implements SuperStoreList
{
private List<String> costcoList;
private KitchenPantry kitchenPantry;
CostcoList(KitchenPantry kitchenPantry)
{
costcoList = new ArrayList<String>();
this.kitchenPantry = kitchenPantry;
kitchenPantry.attach(this);
}
public void update(String item)
{
costcoList.add(item)
}
public void display()
{
System.out.println("Costco list : ");
for(String item : costcoList)
{
System.out.println(item);
}
}
}
public class WalmartList implements SuperStoreList
{
private List<String> walmartList;
private KitchenPantry kitchenPantry;
CostcoList(KitchenPantry kitchenPantry)
{
walmartList = new ArrayList<String>();
this.kitchenPantry = kitchenPantry;
kitchenPantry.attach(this);
}
public void update(String item)
{
walmartList.add(item)
}
public void display()
{
System.out.println("Walmart list : ");
for(String item : walmartList)
{
System.out.println(item);
}
}
}
public class App
{
public static void main(String[] args)
{
KitchenPantry kitchenPantry = new KitchenPantry();
CostcoList costcoList = new CostcoList(kitchenPantry);
WalmartList walmartList = new WalmartList(kitchenPantry);
kitchenPantry.setItem("milk");
costcoList.display();
walmart.display();
}
Hope this helps. Thanks for stopping by.