i currently have a Java Observer/Observable setup in which i switch on some field within the Object parameter of Observer.update (e.g. event id) to determine how to handle an Observable notification.
this creates verbose code like:
public void update (Observable o, Object arg) {
if (arg instanceof Event) {
switch (((Event)arg).getID()) {
case EVENT_TYPE_A:
// do stuff...
break;
case EVENT_TYPE_B:
// do stuff...
break;
case EVENT_TYPE_C:
// do stuff...
break;
}
}
}
coming from an ActionScript background, this feels unnecessarily verbose to me...instead of passing an instance of an Observer, i'd prefer to pass a callback method to be called directly by the Observable (more specifically, by a subclass). however, i'm not clear how to determine the object on which the method should be invoked (the class instance that 'owns' the method).
i could pass a reference to the instance enclosing the method, but this smells like bad OOP.
am i barking up the wrong tree? or is there a clean way to achieve this?
A cleaner implementation would involve removing the logic of whether the event can be handled by the observer/observable, to the actual observer/observable itself. It appears as if ActionScript has left you with a funny idea about the Observer pattern. Observe (no-pun-intended):
public interface Observer{
public void update( Event arg );
}
public class Event{
public int ID;
}
public Button implements Observer{
public void update ( Event arg ){
switch (arg.ID){
case 1: //Buttonsy handle events of type 1
//do something useful;
break;
default:
System.out.println("Buttons don't handle events of ID: " + arg.ID);
break;
}
}
}
public ProgressBar implements Observer{
public void update ( Event arg ){
switch (arg.ID){
case 2: //ProgressBars handle events of type 2 and 3
//do something useful;
break;
case 3:
//do something else useful;
break;
default:
System.out.println("Progress bars don't handle events of ID: " + arg.ID);
break;
}
}
}
public class Subject{
private ArrayList<Observer> allUIControls;
public registerControl( Observer control ){
allUIControls.add( control );
}
public void updateControls ( Event arg ) {
foreach ( Observer control in allUIControls ){
//pass the event to each UI control, and let the EVENT decide if it can understand the Event.ID
//its not the job of Subject to decide if the Observer is fit to handle the event. THIS IS NOT THE OBSERVER pattern.
control.update( arg );
}
}
}