Generic callback in Java
callback, generics, java
Solution
I'd recommend using Observer pattern since the Observer pattern is the gold standard in decoupling - the separation of objects that depend on each other.
But I'd recommend avoiding using the Java.util.Observable class if you are looking for a generic callback mechanism. Because Observable has a couple of weaknesses: it's not an interface, and forces you to use Object to represent events.
You can define your own event listener like this:
public class MyEvent extends EventObject {
public MyEvent(Object source) {
super(source);
}
}
public interface MyEventListener {
void handleEvent(EventObject event);
}
public class MyEventSource {
private final List<MyEventListener> listeners;
public MyEventSource() {
listeners = new CopyOnWriteArrayList<MyEventListener>();
}
public void addMyEventListener(MyEventListener listener) {
listeners.add(listener);
}
public void removeMyEventListener(MyEventListener listener) {
listeners.remove(listener);
}
void fireEvent() {
MyEvent event = new MyEvent(this);
for (MyEventListener listener : listeners) {
listener.handleEvent(event);
}
}
}
Problem
What should be the preferable `Java` interface or similar pattern that could be used as a generic callback mechanism? For example it could be something like ``` public interface GenericCallback { public String getID(); public void callback(Object notification); // or public void callback(String id, Object notification); } ``` The ID would be needed for cases of overriden `hashCode()` methods so that the callee identifies the caller. A pattern like the above is useful for objects that needs to report back to the class they were spawned from a condition (e.g., end of processing). In this scenario, the "parent" class would use the `getID()` method of each of these `GenericCallback` objects to keep a track of them in a `Map<String, GenericCallable>` and add or remove them according to the notification received. Also, how should such an interface be actually named? Many people seem to prefer the Java Observer pattern, but the Observable class defined there is not convenient, since it not an interface to circumvent single inheritance and it carries more functionality than actually needed in the above, simple scenario.