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.

Tuesday, September 3, 2013

python list comprehension for loop

Let's make a 'python list & dictionary comprehension for loop' example. It selects equal or greater than average value, then returns max 50 elements from dictionary.

def pick_biggest_elements(my_dict):
    values = [x for x in my_dict.values()]
    values.sort()
    average = sum(values) / float(len(values))
    upper_side = [el for el in values if el >= average]
    temp = [key for key, value in my_dict.items() if value in upper_side]
    if len(temp) > 50:
        temp = temp[-50:]
    return [eval(a) for a in temp]