Jump to: navigation, search

OTExample Observer/ObservingClose

Application of the Observer pattern

This team is a slight variation of ObservingOpen, also binding the ObserverPattern like this:

A few comments are given inline, for more explanation see below.

  1. package flower_example;
  2.  
  3. import protocol.ObserverPattern;
  4. /**
  5.  * @author Bruce Eckel (original Java example)
  6.  * @author Miguel P. Monteiro (adaptation to OT/J)
  7.  */
  8. public team class ObservingClose extends ObserverPattern {
  9.  
  10.     protected class Subject playedBy Flower
  11.     {
  12.         // This method binding uses a private field of its base class: isOpen
  13.         @SuppressWarnings("decapsulation")
  14.         changeOp <- before close
  15.             base when (base.isOpen);
  16.     }
  17.  
  18.     public class BeeObserver extends Observer playedBy Bee {
  19.         update -> goToBed;
  20.     }
  21.  
  22.     public class HummingbirdObserver extends Observer playedBy Hummingbird {
  23.         update -> bedTime;
  24.     }
  25.  
  26.     // This and the following signature applies OTJLD §2.3.2(e):
  27.     public <AnyBase base Observer>
  28.     void mapSubject2Observer(Flower as Subject subject, AnyBase as Observer observer) {
  29.         subject.addObserver(observer);
  30.     }
  31.  
  32.     public <AnyBase base Observer>
  33.     void removeObserverFromSubject(Flower as Subject subject, AnyBase as Observer observer) {
  34.         subject.removeObserver(observer);
  35.     }
  36.  
  37.     public void removeAllObserversFromSubject(Flower as Subject subject) {
  38.         subject.removeAllObservers();
  39.     }
  40. }

Differences to ObservingOpen

This team class is structurally equivalent to ObservingOpen with one exception: instead of overriding changeOp for conditional behaviour, we've extracted the conditional out off the method and attached it as a guard predicate to the callin binding (see line 15, OTJLD §5.4).

Attaching a guard predicate to a callin binding is used for filtering triggers: only when the guard evaluates to true the callin binding actually fires. By adding the modifier base we say that the guard is evaluated before actually entering the team. This has two consequences: (1) the guard is evaluated in the scope of the base object (denoted by base in the expression) granting direct access to all methods and fields of the base object. (2) the guard is evaluated before the Flower instance is lifted to its Subject role.