Friday, December 6, 2013

java observer pattern

A good example to picture observer pattern is a newspaper subscription service with its publisher and subscribers. The observer pattern defines a one-to-many relationship between a set of objects. When the state of one object changes, all of its dependents are notified. A visualized example of observer pattern is below.

I prepared a little example code of java observer pattern(*). The example acts like a tracker agent that it follows price and stock changes of a product. When price/stock information changes, all observers are updated new price/stock information.

The code includes three interfaces. "Subject" interface which is subscription service. The others are "Observer" and "DisplayProduct".

public interface Subject {
	public void registerObserver(Observer observer);
	public void removeObserver(Observer observer);
	/**
	 * Notify all observers when the Subject's state has changed.
	 */
	public void notifyObservers();
}

/**
 * The Observer interface is implemented by all observers,
 * all observers have to implement the update() method.
 */
public interface Observer {
	public void update(float price, boolean stock);
}

/**
 * It will be called when display product needs to be displayed.
 */
public interface DisplayProduct() {
	public void display();
}

The code includes three classes. "Tracker" implements Subject interface that Tracker object is our subject object as above picture.

public class Tracker implements Subject {
	private ArrayList observers;
	private int price;
	private boolean stock;

	public Tracker() {
		observers = new ArrayList();
	}
	
        public void registerObserver(Observer observer) {
		observers.add(observer);
	}

	public void removeObserver(Observer observer) {
		int index = observers.indexOf(o);
		if (index >= 0) {
			observers.remove(index);
		}
	}

	public void notifyObservers() {
		for (int i=0; i < observers.size(); i++) {
			Observer observer = (Observer)observers.get(i);
			observer.update(price,stock);
		}
	}

	public void stockPriceChanged() {
		notifyObservers();
	}

	public void setStockPrice(float mPrice, boolean mStock) {
		this.price = mPrice;
		this.stock = mStock;
		stockPriceChanged();
	}
}

One of the other classes is "FollowedProductDisplay" which is implements both of Observer and DisplayProduct interfaces. FollowedProductDisplay objects are our observers.

public class FollowedProductDisplay implements Observer, DisplayProduct {
	private float price;
	private boolean stock;
	private Subject tracker;

	public FollowedProductDisplay(Subject mTracker) {
		this.tracker = mTracker;
		tracker.registerObserver(this);
	}

	public void update(float mPrice, boolean mStock) {
		this.price = mPrice;
		this.stock = mStock;
		display();
	}

	public void display() {
		System.out.println("Followed product: price -> " 
                    + price + " stock -> " + stock);
	}
}

The last class is "TrackerAgent" that it contains our subject and observer objects.

public class TrackerAgent {
	public static void main(String[] args) {
		Tracker tracker = new Tracker();
		FollowedProductDisplay followedProduct = 
                        new FollowedProductDisplay(tracker);
		tracker.setStockPrice(124.50,true);
		tracker.setStockPrice(114.50,true);
	}
}

The result of the example is below:

Followed product: price -> 124.50  stock -> true
Followed product: price -> 114.50  stock -> true


(*) I get remarkable help from the book. Head First Design Patterns, Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra, O'Reilly Media, 2004.

No comments:

Post a Comment