Re: generics observer/ observable
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
yancheng.cheok@gmail.com schreef:
Hi all
I wish to have to a generics version of observer/ observable pattern?
just like the one which is implemented in c++ template.
http://www.codeproject.com/cpp/observer_with_templates.asp
I tried the following implementation. However, I get the following
compilation error. May I know what wrongs?
C:\Documents and Settings\yccheok\Desktop\java\observer\src\jstock
\Subject.java:31: update(jstock.Subject<jstock.Observer<T>,T>,T) in
jstock.Observer<T> cannot be applied to
(jstock.Subject<TObserver,T>,T)
package jstock;
/**
*
* @author yccheok
*/
public class Subject<TObserver extends Observer<T>, T> {
Why do you have the TObserver type variable here? It makes everything
overly complicated. Just remove it.
public class Subject<T> {
/** Creates a new instance of Subject */
If your comments are as useful as this one, you can as well leave them out.
public Subject() {
observers = new java.util.concurrent.CopyOnWriteArrayList<
TObserver >();
It is easier to do this at the declaration.
}
public void attach (TObserver observer)
public void attach (Observer<T> observer)
{
observers.add(observer);
}
void _notify (T arg)
May I suggest you use Java naming conventions, not C++ ones?
private void notify (T arg)
{
for(java.util.Iterator< TObserver > iterator =
observers.iterator(); iterator.hasNext(); ) {
iterator.next().update(this, arg);
}
If you use generics, you can use the new foreach syntax as well:
for(Observer<T> obs : observers) {
obs.update(this, arg);
}
}
private List<Observer<T>> observers;
private List<Observer<T>> observers = new
CopyOnWriteArrayList<Observer<T>>();
}
package jstock;
/**
*
* @author yccheok
*/
public interface Observer<T> {
public void update(Subject<T> subject, T arg);
}
Hope that helps.
You can now create a new Subject as follows:
temp = new Subject<Temperature>();
temp.attach(new Observer<Temperature>())
Hm, this is still not satisfactory, since how is the Temperature going
to call notify?
After some guesses about how C++ templating works, I came up with the
following, which seems to behave correctly:
package jstock;
public interface Observer<T> {
public void update(T arg);
}
package jstock;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class Subject<T> {
public void attach(Observer<T> observer) {
observers.add(observer);
}
void notify(T arg) {
for (Observer<T> obs : observers) {
obs.update(arg);
}
}
private List<Observer<T>> observers = new
CopyOnWriteArrayList<Observer<T>>();
}
package jstock;
public class Temperature extends Subject<Temperature> {
void temperatureChanged() {
notify(this);
}
void getTemperature() {
System.out.println("Getting the temperature.");
}
}
package jstock;
public class PanicSirene implements Observer<Temperature> {
public void update(Temperature subject) {
System.out.println("Temperature was changed, sound the sirene");
subject.getTemperature();
}
static public void main(String[] args) {
Temperature temp = new Temperature();
PanicSirene panic = new PanicSirene();
temp.attach (panic);
temp.temperatureChanged ();
}
}
And it seems to work:
test Java> java jstock/PanicSirene
Temperature was changed, sound the sirene
Getting the temperature.
Phieuw, quite some more work than I thought
H.
- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGMiE5e+7xMGD3itQRAuzYAJwKr+2g4pDTp/4napl/wbHuYNqT7ACfaHCG
rurJfFH6OH2H46eSX5IPp2M=
=Kydq
-----END PGP SIGNATURE-----