Observer and Observable usage
807580May 14 2010 — edited May 14 2010Hello!
Please consider the following (working) snippets of code:
#1 - main program:
import java.util.Observable;
import java.util.Observer;
public class DemoApp {
private Model m;
private MyView v;
public DemoApp() {
m = new Model();
v = new MyView(m);
m.addObserver(v);
}
public void updateModel() {
m.updateModelState();
}
public void showMe() {
v.showView();
}
public static void main(String[] args) {
DemoApp demo = new DemoApp();
for (int i=0;i<25;i++) {
demo.updateModel();
demo.showMe();
}
}
}
#2 - The Observable model:
import java.util.Observable;
import java.util.Observer;
public class Model extends Observable {
private int MyData;
public Model() {
MyData = 0;
}
public void updateModelState() {
MyData++;
setChanged();
notifyObservers();
}
public int getMyData() {
return MyData;
}
}
#3 - The observing View:
import java.util.Observable;
import java.util.Observer;
public class MyView implements Observer {
private int displayValue;
public MyView(Model m) {
displayValue = m.getMyData();
}
public void update(Observable thing, Object obj) {
//displayValue = ((Model)thing).getMyData();
}
public void showView() {
System.out.println("Update: MyData is now "+displayValue);
}
}
Two questions:
#1:
Obviously these are all stripped version of the real thing, where the view is a swing component and the data model being fetched/displayed is a complicated set of mixed-format data. Now, this works well as it does, but I can't help to think it would be cleaner if I could somehow rid myself of the need to pass the model reference to the observer specifically. Unfortunately, I run into a catch-22 situation - the model cannot add the view as a listener unless the view has already been initialized, and the model can't get an object reference to call the data export method from the model for the initial initialization from the update method, since it is not yet an registered Observer during the set-up. I can't fill the View with dummy data either, since a real update might be long in the coming. Is there a smart way around this that would allow me to call MyView v = new MyView(), not new MyView(m)?
#2:
The cast in the update method of the view; "displayValue = ((Model)thing.getMyData();" is awkward since it forces me to know the passed Observable's class to be able to call methods on it. I might really just as well just store the passed Model m parameter as a class attribute in MyView and just do a "displayValue = m.getMyData();" in the update instead, since I need to know the class anyway. Is there a way to avoid having to have this knowledge hard-coded in the MyView object? Ideally I would like all the communication to pass through the Observer/Observable interface methods and not have my various components keep references and class information about each other.
TIA,
GMA