OBSERVER PATTERN

In observer design pattern multiple observer objects registers with a subject for change notification. When the state of subject changes, it notifies the observers. Objects that listen or watch for change are called observers and the object that is being watched for is called subject.

Pattern involved is also called as publish-subscribe pattern.

  • Subject provides interface for observers to register and unregister themselves with the subject.
  • Subject knows who its subscribers are.
  • Multiple observers can subscribe for notifications.
  • Subject publishes the notifications.
  • Subject just sends the notification saying the state has changed. It does not pass any state information.
  • Once the notification is received from subject, observers call the subject and get data that is changed.

The above last two points are not strictly followed in observer design pattern implementation. Along with the notification, state is also passed in some implementation so that the observer need not query back to know the status. It is better not to do this way.

There are four participants in the Observer pattern:

* Subject, which is used to register observers. Objects use this interface to register as observers and also to remove themselves from being observers.

* Observer defines an updating interface for objects that should be notified of changes in a subject. All observers need to implement the Observer interface. This interface has a method update (), which gets called when the Subject’s state changes.

* ConcreteSubject, stores the state of interest to ConcreteObserver objects. It sends a notification to its observers when its state changes. A concrete subject always implements the Subject interface. The notifyObservers () method is used to update all the current observers whenever the state changes.

* ConcreateObserver maintains a reference to a ConcreteSubject object and implements the Observer interface. Each observer registers with a concrete subject to receive updates.

Java provides inbuilt platform for implementing Observer pattern through java.util.Observable class and java.util.Observer interface. However it’s not widely used because the implementation is really simple and most of the times we don’t want to end up extending a class just for implementing Observer pattern as java doesn’t provide multiple inheritances in classes.

Example:
Let us take a blog and subscriber example for observer design pattern sample implementation. Assume that there is a blog and users register to that blog for update. When a new article is posted in the blog, it will send update to the registered users saying a new article is posted. Then the user will access the blog and read the new article posted. In this example, blog is the subject and user is the observer.

package com.myjavablog.behavioural.observer;

public interface Subject {

public void registerObserver(Observer observer);
public void notifyObserver();
public void unregisterObserver(Observer observer);
public Object getUpdate();
}

package com.myjavablog.behavioural.observer;

public interface Observer {

public void update();
public void setSubject(Subject sub);
}

package com.myjavablog.behavioural.observer;

import java.util.ArrayList;
import java.util.List;

//Concrete Subject
public class Blog implements Subject {

List<Observer> observerList;
private boolean stateChange;

public Blog(){
this.observerList = new ArrayList<>();
stateChange = false;
}

@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}

@Override
public void notifyObserver() {
if(stateChange){
for(Observer observer: observerList){
observer.update();
System.out.println("Observer notified!!");
}
}
}

@Override
public void unregisterObserver(Observer observer) {
observerList.remove(observer);
}

@Override
public Object getUpdate() {

Object changedState = null;

//Should have a logic to send state change to the querying observer
if(stateChange){
changedState = "Observer Design Pattern";
}

return changedState;
}

public void postNewArticle(){
stateChange = true;
notifyObserver();
}
}

package com.myjavablog.behavioural.observer;

//Concrete Observer
public class User implements Observer {

private String article;
private Subject blog;

@Override
public void update() {
System.out.println("State change reported by subject");
article = (String) blog.getUpdate();
}

@Override
public void setSubject(Subject blog) {
this.blog = blog;
article = "No new article!";
}

public String getArticle(){
return article;
}
}

package com.myjavablog.behavioural.observer;

public class ObserverPatternTest {

public static void main(String[] args) {
Blog blog = new Blog();
User user1 = new User();
User user2 = new User();
blog.registerObserver(user1);
blog.registerObserver(user2);
user1.setSubject(blog);
user2.setSubject(blog);
System.out.println(user1.getArticle());
blog.postNewArticle();
System.out.println(user1.getArticle());
}
}

Output:

No new article!
State change reported by subject
Observer notified!!
State change reported by subject
Observer notified!!
Observer Design Pattern

When to use the Observer Pattern:

Use the Observer pattern in any of the following situations:

  • When an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently.
  • When a change to one object requires changing others, and you don’t know how many objects need to be changed?
  • When an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don’t want these objects tightly coupled.

Usage in Java:

  • java.util.EventListener in Swing
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAttributeListener

 

 

Leave a Comment

Bitnami