[otj-users] Using ObserverPattern

Marco Mosconi mosconi at cs.tu-berlin.de
Thu Jul 10 19:56:16 CEST 2008


Hi Miguel,

see answers below:

> Question 1:
> I would like to to map subject objects to observer objects dynamically, which means
> using role method addObserver. Unfortunately, the example on the OT/J site does not
> use this and other methods. It is not clear how can they to be used. I experimented
> several variants, but some compiler error always gets in the way. So, how do I call
> addObserver from main? My original intention was to pass base objects as arguments:
> instances of classes Bee and Hummingbird, which play the Subject role.
In the example implementation of ObserverPattern the intended way is to 
use Observer.start(Subject) instead of Subject.addObserver(Observer).
This works with your example. (You could also make addObserver() public 
in ObserverPattern to use it directly.)
BTW, there are more up-to-date implementations of this and other 
examples included in the OTDT distribution (Welcome->Samples).

> Question 2:
> It seems that playedBy cannot be used to bind more than one base class to a role. To
> circumvent, I resorted to two subclasses of role Observer: BeeObserver and
> HummingbirdObserver. Would this be the recommended way to bind more than one class
> to a role?
Exactly. This way you can impose a "virtual" inheritance structure over 
the otherwise unrelated base classes.
Binding multiple base classes is not supported for several reasons. In 
your example it wouldn't even make sense because you have different base 
methods to callout-bind the update() method, depending on the bound base 
type.

> Question 3:
> At some point, I tried to encapsulate the role methods with team methods, the way
> Stephan suggested in an old post (2005 Sep 7 - "role object creation considered
> complex?"). However, the parameter declaration 'Base as Role param' does not seem to
> be polymorphic, which forced me to duplicate encapsulating methods (mapSubject2Bee
> and mapSubject2Hummingbird). Surely there is a better way, but how?
AFAIK there is no better solution for your example, because Bee and 
Hummingbird are not type-related.
If they had a common super-type you could define one polymorphic 
register method for both. Otherwise you could only use overloading to 
streamline the team interface.

> Question 4:
> I get compiler error "A non-abstract role method exists for this callout-binding.
> Use callout-override ('=>')". This error puzzles me, as update is declared abstract
> in the role. What is the the cause?
I can't see this error with your code example. Perhaps it is a follow-up 
of another error? Please try a Clean/Build.

Best regards,
Marco

> Thanks in advance,
> mpm
> 
> ----------------------------------------------------------------------
> //Base class to play the "Subject" role
> public class Flower {
>    private boolean isOpen;
> 
>    public Flower() {
>       isOpen = false;
>    }
>    // Opens its petals
>    public void open() {
>       isOpen = true;
>       System.out.println("open");
>    }
>    //Closes its petals
>    public void close() {
>       isOpen = false;
>       System.out.println("close");
>    }
> }
> ----------------------------------------------------------------------
> //Base class to play the "Observer" role
> public class Bee {
>    private String _name;
> 
>    public Bee(String name) {
>       _name = name;
>    }
>    //Reaction to Flower.open
>    public void haveBreakfast() {
>       System.out.println("Bee " + _name + "'s breakfast time!");
>    }
>    //Reaction to Flower.close
>    public void goToBed() {
>       System.out.println("Bee " + _name + "'s bed time!");
>    }
> }
> ----------------------------------------------------------------------
> //Another "Observer" base class; similar to Bee, though type-unrelated
> //and with a different interface.
> public class Hummingbird {
>    private String _name;
> 
>    public Hummingbird(String name) {
>       _name = name;
>    }
>    //Reaction to Flower.open
>    public void breakfastTime() {
>       System.out.println("Hummingbird " + _name + "'s time to have breakfast!");
>    }
>    //Reaction to Flower.close
>    public void bedTime() {
>       System.out.println("Hummingbird " + _name + " goes to sleep!");
>    }
> }
> ----------------------------------------------------------------------
> public team class ObservingOpen extends ObserverPattern {
> 
>    public void mapSubject2Bee(Flower as Subject subject, Bee as Observer observer) {
>       subject.addObserver(observer);
>    }
> 
>    public void mapSubject2Hummingbird(Flower as Subject subject, Hummingbird as
> Observer observer) {
>       subject.addObserver(observer);
>    }
> 
>    public class Subject playedBy Flower {
>            changeOp <- after open;
>        }
>    public class BeeObserver extends Observer playedBy Bee {
>       update -> haveBreakfast;
>    }
>    public class HummingbirdObserver extends Observer playedBy Hummingbird {
>       update -> breakfastTime;
>    }
> }
> 
> ----------------------------------------------------------------------
> //Driver for the example
> public class Main {
>    public static void main(String[] args) {
>       /*final*/ ObservingOpen observationRelationship = new ObservingOpen();
>       observationRelationship.activate();
> 
>       Flower flower = new Flower();
> 
>       Bee beeA = new Bee("A");
>       Bee beeB = new Bee("B");
>       observationRelationship.mapSubject2Bee(flower, beeA);
>       observationRelationship.mapSubject2Bee(flower, beeB);
> 
>       Hummingbird ha = new Hummingbird("A"), hb = new Hummingbird("B");
>       observationRelationship.mapSubject2Hummingbird(flower, ha);
> 
>       // A change that interests observers:
>       flower.open();
>       flower.close();
>       observationRelationship.deactivate();
>       System.out.println("\nterminated.");
>    }
> }
> ----------------------------------------------------------------------
> 

-- 
Dipl.-Inform. Marco Mosconi
Technische Universität Berlin
Fak. IV, Fachg. Softwaretechnik



More information about the otj-users mailing list