generics observer/ observable

Y

yancheng.cheok

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> {

/** Creates a new instance of Subject */
public Subject() {
observers = new java.util.concurrent.CopyOnWriteArrayList<
TObserver >();
}

public void attach (TObserver observer)
{
observers.add(observer);
}

void _notify (T arg)
{
for(java.util.Iterator< TObserver > iterator =
observers.iterator(); iterator.hasNext(); ) {
iterator.next().update(this, arg);
}
}

private java.util.List< TObserver > observers;
}


package jstock;

/**
*
* @author yccheok
*/
public interface Observer<T> {
public void update(Subject< Observer<T>, T > subject, T arg);
}
 
H

Hendrik Maryns

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

(e-mail address removed) 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 said:
/** 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 said:
{
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 said:
}


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-----
 
D

Daniel Pitts

(e-mail address removed) schreef:

May I suggest you use Java naming conventions, not C++ ones?

private void notify (T arg)

Actually, I would suggest choosing another name altogether. There is
a method called notify in the Object class. It might be better to
call it void observe(T arg);
 
J

jacma983

Actually, I would suggest choosing another name altogether. There is
a method called notify in the Object class. It might be better to
call it void observe(T arg);

nitpicking but...

In the Observer/Observable pattern it's the observer
that observes the subject: not the other way round.

So maybe notifyObservers() ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,697
Latest member
AugustNabo

Latest Threads

Top