It consists of two classes namely Observer and Observable and in simplified form looks like this:
public interface Observer { void update(Observable observable); }
public class Observable { public void addObserver(Observer observer) { } public void notifyObservers() { } }
Let's assume that we want to have two distinct subclasses of Observer and Observable. ObserverA can observe instances of ObservableA only and ObserverB can observe instances of ObservableB only.
How should we define all those classes to enforce correct behaviour? As simple as this question seems to be the solution might not be as obvious for people who don't know generics too much.
The solution is to parametrize both Observer and Observable with two type parameters one for Observer subclass and the other one for Observable subclass.
public interface Observer<T extends Observer<T,O>, O extends Observable<O,T>> { void update(O observable); }
public class Observable<T extends Observable<T,O>, O extends Observer<O,T>> { public void addObserver(O observer) { } public void notifyObservers() { } }
public interface ObserverA extends Observable<ObserverA, ObservableA> { }
public class ObservableA extends <ObservableA, ObserverA > { }
Thanks to this ObserverA.update() will accept subclasses of ObservableA only and ObservableA.addObserver() will accept subclasses of ObserverA.
The same solution can be applied to any set of classes which depend on each other. In this context simply parametrize each of them with one type parameter for each of the classes.
Brilliant, exactly what I was looking for!
OdpowiedzUsuń