Im Folgenden wird die Schnittstelle
                    IObservableValue vorgestellt und es werden
                    existierende Default Implementierungen gezeigt.
                  
         
                         Die Schnittstelle IObservableValue sieht
                         wie folgt aus:
                       
            
  1  public interface IObservableValue<VALUE_TYPE> {
  2  
  3      void setValue(VALUE_TYPE value);
  4  
  5      VALUE_TYPE getValue();
  6  
  7      void addValueListener(IObservableValueListener<?> listener);
  8  
  9      void removeValueListener(IObservableValueListener<?> listener);
 10  }
                         Ein IObservableValueListener hat die
                         folgende Methode:
                       
            
    void changed(IObservableValue<VALUE_TYPE> observableValue, VALUE_TYPE value);
                         Man bekommt sowohl den Observable Value der sich geändert hat,
                         als auch den neuen Wert (value) übergeben.
                         Der Listener feuert nur dann, wenn sich der Wert tatsächlich
                         geändert hat. Wird zum Beispiel ein zweites mal der gleiche
                         Wert gesetzt, wird kein ChangedEvent geworfen.
                       
            
                         Die Klasse ObservableValue bietet eine
                         Default Implementierung der Schnittstelle
                         IObservableValue.
                       
            
                         Das folgende Beispiel demonstriert die Verwendung der Klasse
                         ObservableValue:
                       
            
  1      final IObservableValue<IPerson> forkliftDriver = new ObservableValue<IPerson>(dieter);
  2          
  3      forkliftDriver.addValueListener(new IObservableValueListener<IPerson>() {
  4          @Override
  5          public void changed(final IObservableValue<IPerson> observableValue, final IPerson value) { 
  6              diaphone.setActive(value == klaus);
  7          }
  8      });
  9          
 10      forkliftDriver.setValue(klaus);
                         Die Default Implementierung implementiert
                         nicht equals() und
                         hashCode(). Zwei ObservableValue Objekte
                         sind insbesondere nicht
                         equal, wenn ihre values gleich sind. Der
                         folgende UnitTest soll verdeutlichen, warum:
                       
            
1 final ObservableValue<String> value = new ObservableValue<String>(); 2 value.setValue(STRING_1); 3 4 final Set<ObservableValue<String>> set = new HashSet<ObservableValue<String>>(); 5 set.add(value); 6 7 value.setValue(STRING_2); 8 9 Assert.assertTrue(set.remove(value));
                         Durch das Ändern des Wertes in Zeile 7 würde sich der
                         hasCode() ändern, wodurch der value nicht
                         mehr aus der Liste entfernt werden könnte.
                       
            
                         Die Klasse ObservableValue wurde so
                         entworfen, dass davon abgeleitet werden kann. Das folgenden
                         Beispiel zeigt eine ObservablePerson,
                         welche equals() und
                         hashCode() mit Hilfe einer id
                         implementiert:
                       
            
  1  import org.jowidgets.util.Assert;
  2  import org.jowidgets.util.ObservableValue;
  3  
  4  public final class ObservablePerson extends ObservableValue<IPerson> {
  5  
  6      private final Object id;
  7  
  8      public ObservablePerson(final Object id) {
  9          Assert.paramNotNull(id, "id");
 10          this.id = id;
 11      }
 12  
 13      @Override
 14      public int hashCode() {
 15          final int prime = 31;
 16          int result = 1;
 17          result = prime * result + ((id == null) ? 0 : id.hashCode());
 18          return result;
 19      }
 20  
 21      @Override
 22      public boolean equals(final Object obj) {
 23          if (this == obj) {
 24              return true;
 25          }
 26          if (obj == null) {
 27              return false;
 28          }
 29          if (!(obj instanceof ObservablePerson)) {
 30              return false;
 31          }
 32          final ObservablePerson other = (ObservablePerson) obj;
 33          if (id == null) {
 34              if (other.id != null) {
 35                  return false;
 36              }
 37          }
 38          else if (!id.equals(other.id)) {
 39              return false;
 40          }
 41          return true;
 42      }
 43  
 44  }
                         Um ein IObservableValue mit Hilfe des
                         Wrapper Patters zu wrappen, zum Beispiel
                         um den Wert zu dekorieren, kann die Klasse
                         ObservableValueWrapper verwendet werden.
                         Das folgende Beispiel soll das verdeutlichen:
                       
            
  1  import org.jowidgets.util.IDecorator;
  2  import org.jowidgets.util.IObservableValue;
  3  import org.jowidgets.util.ObservableValueWrapper;
  4  
  5  public final class ObservableValueDecorator<VALUE_TYPE> 
  6      implements IDecorator<IObservableValue<VALUE_TYPE>> {
  7  
  8      //injected
  9      private IAuthorizationService authorizationService;
 10  
 11      @Override
 12      public IObservableValue<VALUE_TYPE> decorate(final IObservableValue<VALUE_TYPE> original) {
 13          if (authorizationService == null) {
 14              return original;
 15          }
 16          else {
 17              return new ObservableValueWrapper<VALUE_TYPE>(original) {
 18                  @Override
 19                  public void setValue(final VALUE_TYPE value) {
 20                      if (!authorizationService.hasAuthorization(Authorizations.UPDATE)) {
 21                          throw new SecurityException("No authorization for update");
 22                      }
 23                      else {
 24                          super.setValue(value);
 25                      }
 26                  }
 27              };
 28          }
 29      }
 30  }
                         Die Klasse MandatoryObservableValue liefert
                         eine Implementierung von IObservableValue
                         welche nicht den Wert null annehmen kann.
                         Die Implementierung sieht wie folgt aus:
                       
            
  1  public class MandatoryObservableValue<VALUE_TYPE> extends ObservableValue<VALUE_TYPE> {
  2  
  3      private final VALUE_TYPE defaultValue;
  4  
  5      public MandatoryObservableValue(final VALUE_TYPE defaultValue) {
  6          Assert.paramNotNull(defaultValue, "defaultValue");
  7          this.defaultValue = defaultValue;
  8      }
  9  
 10      @Override
 11      public void setValue(final VALUE_TYPE value) {
 12          if (value != null) {
 13              super.setValue(value);
 14          }
 15          else {
 16              super.setValue(defaultValue);
 17          }
 18      }
 19  
 20      @Override
 21      public VALUE_TYPE getValue() {
 22          final VALUE_TYPE superResult = super.getValue();
 23          if (superResult != null) {
 24              return superResult;
 25          }
 26          else {
 27              return defaultValue;
 28          }
 29      }
 30  }
                         Ein MandatoryObservableValue hat einen
                         Default Value (Zeile 3), welcher verwendet wird, sobald
                         null gesetzt wird.
                       
            
                         Ein ObservableBoolean liefert eine
                         Implementierung von IObservableValue für
                         ein Boolean bei dem nicht gewünscht ist,
                         dass der Wert null angenommen werden kann,
                         sondern nur true und
                         false. Die Implementierung sieht wie folgt
                         aus:
                       
            
  1  public final class ObservableBoolean extends ObservableValue<Boolean> {
  2  
  3      public ObservableBoolean() {
  4          setValue(false);
  5      }
  6  
  7      public ObservableBoolean(final boolean value) {
  8          set(value);
  9      }
 10  
 11      public boolean get() {
 12          return getValue().booleanValue();
 13      }
 14  
 15      public void set(final boolean value) {
 16          super.setValue(Boolean.valueOf(value));
 17      }
 18  
 19      @Override
 20      public void setValue(final Boolean value) {
 21          Assert.paramNotNull(value, "value");
 22          super.setValue(value);
 23      }
 24  }
                         Die Methoden get() und
                         set() bieten einen komfortablen Zugriff auf
                         den kleinen boolean ohne
                         Autoboxing.[26] Der Ausdruck boolean b = get()
                         kann (im Vergleich zu
                         boolean b = getValue() auf einen
                         herkömmlichen Observable Value) nie eine
                         NullPointerException werfen, da man das
                         Setzen von null explizit verhindert (Zeile
                         21). Man sollte einen solchen Wert nur an Observable Values
                         binden, die ebenfalls Mandatory sind. Man könnte den Code ab
                         Zeile 21 auch wie folgt ändern:
                       
            
  1      @Override
  2      public void setValue(final Boolean value) {
  3          if (value != null){
  4              super.setValue(value);
  5          }
  6          else{
  7              super.setValue(Boolean.FALSE);
  8          }
  9      }Dies würde dem Verhalten des MandatoryObservableValue entsprechen, wobei man zusätzlich noch die sichere get() Methode hat.
[26] Warum Atoboxing evil ist, wird unter anderem auch hier diskutiert: [https://pboop.wordpress.com/2010/09/22/autoboxing-is-evil/]