This is the follow-up question from here.
This is an Observable
class similar to java.util.Observable
. The difference is that it uses generics to avoid casts.
There are two questions:
- Is it really worth the effort? or it's just making things more complex than needed?
- Should this class be declared
final
, or is it ok to be subclassed? java.util.Observable is not final.
package cc.koosha.silkroad.lang;
import java.util.ArrayList;
import java.util.Collection;
/**
* like java.util.Observable, But uses generics to avoid need for a cast.
* For any un-documented variable, parameter or method, see java.util.Observable
*/
public class Observable<T> {
public interface Observer<T> {
public void update(Observable observable, T args);
}
/**
* Holds registered observers.
* @TODO if class is not final can we make this protected? (should we?).
*/
private final Collection<Observer<? super T>> registry;
private boolean changed = false;
/**
* @TODO should this be private and the class final?.
*/
protected Observable(final Collection<Observer<? super T>> registry) {
this.registry = registry;
}
/**
* Static constructor.
*/
public static <F> Observable<F> getInstance() {
ArrayList<Observer<? super F>> container = new ArrayList<Observer<? super F>>();
return new Observable<F>(container);
}
// @TODO Should o be checked for null?
public void addObserver(final Observer<? super T> o) {
synchronized (this.registry) {
if (!this.registry.contains(o))
this.registry.add(o);
}
}
protected void update(final T args) {
ArrayList<Observer<? super T>> toNotify;
synchronized (this.registry) {
if (!changed)
return;
toNotify = new ArrayList<Observer<? super T>>(this.registry);
this.changed = false;
}
// Look at OpenJDK to see why a new Collection is used.
for (Observer<? super T> o : toNotify)
o.update(this, args);
}
public void notifyObservers(final T args) {
this.update(args);
}
Methods deleteObserver
, deleteObservers
, setChanged
, clearChanged
, hasChanged
, countObservers
, notifyObservers
are removed for brevity.
The rest of the code is at GitHub.