Friday, January 23, 2015

Observer Design Pattern

Design Pattern > Behavioral Design Pattern > Observer Design Pattern

In some scenarios you can see one to many relation between objects i.e. if there is change in state of parent object all child objects should get updated/notified.

Here, dependent objects can directly access the state of parent/observable object if we make state public to observers but it would fail the encpsulation principle and objects would be tightly coupled in this case.
Observer design pattern helps in this scenario.

In observer design pattern there are 3 clasess. Subject - whose change state is observed, Observer - observe subject for state change, Client - class which create instances of subject and observers, change state of subject.

Observer pattern is also know as publish-subscribe pattern.

Key Terms :

Subject -

  • An interface or abstract class
  • Contains a list of observers
  • provide interfaces to subscribe or unsubscribe observers objects


ConcreteSubject -

  • Implements/extends Subject
  • Stores its state information
  • notifies it's observers when state changes


Observer -

  • An interface or abstract class 
  • Has reference to subjet
  • Define a update state method for observers to make them in consistent with subject


ConcreateObserver -

  • Implements/extends Observer
  • Subscribe itself for subject state change while initializing
  • Implement a update state method for observers to make them in consistent with subject


Client -

  • Instantiate Subject
  • Instantiate Observers
  • Changes state of subject


Benefits of Using Observer Pattern :

Minimal coupling between the Subject and the Observer

  • Can reuse subjects without reusing their observers and vice versa
  • Observers can be added without modifying the subject
  • All subject knows is its list of observers
  • Subject does not need to know the concrete class of an observer, just that each observer implements the update interface
  • Subject and observer can belong to different abstraction layers

Support for event broadcasting

  • Subject sends notification to all subscribed observers
  • Observers can be added/removed at any time


Java Inplementation:
In key terms section we have seen the pseudo code, now let's see actual java implementation


/**
 * Subject abstract class
 */
package com.kmingle.observer;

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

public abstract class Publisher {

protected List observerList = new ArrayList();

public abstract void SubscribeMe(Observer observer);

public abstract void UnSubscribeMe(Observer observer);

}


/**
 *  Concrete Subject 
 */
package com.kmingle.observer;


public class EnglishPublisher extends Publisher {

private String state;

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
notifyObservers();
}

/* (non-Javadoc)
* @see com.kmingle.observer.Publisher#SubscribeMe()
*/
@Override
public void SubscribeMe(Observer observer) {

observerList.add(observer);
System.out.println(observer.observerName+" subscribed");
}

/* (non-Javadoc)
* @see com.kmingle.observer.Publisher#UnSubscribeMe()
*/
@Override
public void UnSubscribeMe(Observer observer) {

observerList.remove(observer);
System.out.println(observer.observerName+" unsubscribed");

}

public void notifyObservers(){

for(Observer o : observerList){
o.update();
}
}

}


/**
 * Observer Interface
 */
package com.kmingle.observer;


public abstract class Observer {

String observerName;
protected Publisher publisher;
abstract void update();
}


/**
 * Concerete Observer
 */
package com.kmingle.observer;


public class EnglishSubsriber extends Observer {


public EnglishSubsriber(Publisher pub, String name){
this.observerName = name;
this.publisher = pub;
this.publisher.SubscribeMe(this);
}

/* (non-Javadoc)
* @see com.kmingle.observer.Observer#update()
*/
@Override
public void update() {

System.out.println("updated state in "+this.observerName +" is " +((EnglishPublisher) publisher).getState());
}

}


/**
 * Client Class
 */
package com.kmingle.observer;


public class ObserverDemo {


public static void main(String[] args) {

EnglishPublisher engPublisher = new EnglishPublisher();

new EnglishSubsriber(engPublisher, "Observer1");

new EnglishSubsriber(engPublisher, "Observer2");

System.out.println("changing state of subject");

engPublisher.setState("statechanged");

System.out.println("rechanging state of subject");

engPublisher.setState("REstatechanged");
}

}

OutPut :

Observer1 subscribed
Observer2 subscribed
changing state of subject
updated state in Observer1 is statechanged
updated state in Observer2 is statechanged
rechanging state of subject
updated state in Observer1 is REstatechanged
updated state in Observer2 is REstatechanged



Further, You can create more than one Publisher classes i.e. Subjects

No comments:

Total Pageviews