We looked a bit at the role of classes and interfaces, and then at the “Observer” design pattern. Here’s a simple example of an observable counter model, and two different kinds of observers that are updated when the counter changes.
package net.liucs.java;
import java.util.Observable;
import java.util.Observer;
class Counter extends Observable {
private int x = 0;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
setChanged();
notifyObservers();
}
}
class ValueAnnouncer implements Observer {
@Override
public void update(Observable observable, Object o) {
Counter c = (Counter) observable;
System.out.println("Announcing a new value: " + c.getX());
}
}
class BarGraph implements Observer {
@Override
public void update(Observable observable, Object o) {
Counter c = (Counter) observable;
int x = c.getX();
for(int i = 0; i < x; i++) {
System.out.print("*");
}
System.out.println();
}
}
class Example {
static public void main(String[] args) {
Counter c = new Counter();
ValueAnnouncer va = new ValueAnnouncer();
c.addObserver(va);
BarGraph bg = new BarGraph();
c.addObserver(bg);
System.out.println("Counter is " + c.getX());
c.setX(42);
System.out.println("Counter is now " + c.getX());
c.setX(19);
}
}
The output of the main program is:
Counter is 0
******************************************
Announcing a new value: 42
Counter is now 42
*******************
Announcing a new value: 19