This tutorial shows you how to implement the Observer Design Pattern using a built in Java Class & Interface.
Prerequisite, basic knowledge of:
- Composition
- Inheritance
- Interfaces
Design patterns - tried and tested methods for solving commonly occuring problems in software development
Observer Pattern
Typical problem domain:
- when an object needs to notify other object(s) that are interested in its state of a change
Typical use cases:
- a mailing list, where every time an event happens (a new product, a gathering, etc.) a message is sent to the people subscribed to the list.
- Model/View/Controller: where the view needs to fetch/data information about the model or the model needs to notify the view of a change.
Example Problem Domain.
Imagine an airport system, that needs to notify its passengers of potential delays due to a natural occurrence such as a Volcanic Ash or other reasons.
In this case, the Volcanic Ash is what is going to be observed so: VolcanicAsh == Observable.
The passengers are going to be the ones observing & notified of changes so: Passengers == Observers.
All we are simply going to do is store a value for how long the VolcanicAsh is going to delay the flight for passengers and create a method to update this value, notifying the passengers of each change.
Observer & Observable
The Java library provides support with an Interface and a Class to provide support of implementing this pattern.
The VolcanicAsh is going to be a subclass of Observable.
Observable is a class in Java which has the following useful and self explanatory methods:
- addObserver(Observer obs)
- deleteObserver(Observer obs)
- deleteObservers()
- countObservers()
- setChanged() // Sets the internal flag that indicates this observable has changed
- clearChanged()
- hasChanged() // returns whether the observable object's state has changed
- notifyObservers() // notifies all the observers registered with it.
- notifyObservers(Object obj) // notifies all observers with a value
Here is how this is implemented in Java:
package observerExample;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
public class VolcanicAshCloud extends Observable{
// current number of days
private int numberofDaysDelay;
// used to notify passengers of the delay
// positive value for increased delay
// negative value for improved conditions
public void addDelay(int days){
this.numberofDaysDelay += days;
this.setChanged();
// sends a message to all of its observers with the change
this.notifyObservers(new Integer(days));
}
}
The Passengers, being the ones who are observing changes in flight caused by the Volcanic Ash will be the observers. This is done by implementing the Observer interface. It is required to implement a method called update will gets invoked each time the Observable notifies it of a change by the Observable passing itself along with an argument to the Observers update method.
package observerExample;
import java.util.Observable;
import java.util.Observer;
public class Passenger implements Observer {
private int delay = 0;
public Passenger(){};
// automatically invoked by the Observable passing itself as well any
// argument to this method. Used to notify the passenger
@Override
public void update(Observable observable, Object arg) {
int new_delay = (Integer) arg;
this.delay += new_delay;
// If this is executing because of the volcanic ash cloud.
if (observable instanceof VolcanicAshCloud) {
if(new_delay > 0){
System.out.println("The flight has been delayed for another " + this.delay + " days");
}else{
System.out.println("The flight is only now delayed by " + this.delay + " days");
}
}
}
}
Finally we will create a method where for the sake of simplicity, passengers will be notified of changes to their flight due to a volcanic ash.
package observerExample;
public class Test {
public static void main(String[] args){
VolcanicAshCloud v = new VolcanicAshCloud();
// create 3 passengers and register them with the Volcanic Ash update
List<Passenger> pList = new ArrayList<Passenger>();
for(int i = 0; i < 3; i++){
pList.add(new Passenger());
v.addObserver(pList.get(i));
}
// uh oh, there has been a delay in the weather
v.addDelay(3);
System.out.println();
// ok, looks like its worse than first feared
v.addDelay(4);
System.out.println();
// we got it wrong again, looks like the weather has improved
// and this time we're sure we got it right
v.addDelay(-5);
}
}
The output should look like this:
The flight has been delayed for another 3 days The flight has been delayed for another 3 days The flight has been delayed for another 3 days The flight has been delayed for another 7 days The flight has been delayed for another 7 days The flight has been delayed for another 7 days The flight is now only delayed by 2 days The flight is now only delayed by 2 days The flight is now only delayed by 2 days
References + Further reading:
http://www.javaworld...wto.html?page=3
http://java-x.blogsp...rn-in-java.html





MultiQuote





|