Difference between revisions of "JFace Data Binding/Observable"

From Eclipsepedia

Jump to: navigation, search
m
m (Observable moved to JFace Data Binding/Observable: Moving all JFace Data Binding pages to be children of the main page.)
 
(7 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
Observables are one of the key abstractions provided by [[JFace Data Binding]] and are an implementation of the [http://en.wikipedia.org/wiki/Observer_pattern Observer pattern].  They provide a common abstraction for observing changes in objects.
 
Observables are one of the key abstractions provided by [[JFace Data Binding]] and are an implementation of the [http://en.wikipedia.org/wiki/Observer_pattern Observer pattern].  They provide a common abstraction for observing changes in objects.
 
+
{{JFace Data Binding}}
 
== Core Interfaces of Interest ==
 
== Core Interfaces of Interest ==
* IObservable
+
* IObservable - super-interface of all observables, allows to listen for generic change events
* IObservableValue
+
* IObservableValue - has getValue(), setValue(), and allows to listen for value change events
* IVetoableValue
+
* IVetoableValue - inherits from IObservableValue, and allows to listen for before-change events
* IObservableCollection
+
* IObservableCollection - extends java.util.Collection and IObservable
* IObservableList
+
* IObservableList - extends java.util.List and IObservableCollection, and allows to listen for incremental list change events
* IObservableSet
+
* IObservableSet - extends java.util.Set and IObservableCollection, and allows to listen for incremental set change events
* IObservableMap
+
* IObservableMap - extends java.util.Map and IObservable, and allows to listen for incremental map change events
  
 
== Implementation Design Principles ==
 
== Implementation Design Principles ==
 
# An observable must remove listeners on the observed when disposed.  For example if you registered selection listeners on a widget when the observable was constructed it must remove these on dispose of the observable.
 
# An observable must remove listeners on the observed when disposed.  For example if you registered selection listeners on a widget when the observable was constructed it must remove these on dispose of the observable.
 
# An observable should fire change events when the value changes if at all possible.  This means when the value changes in the object being observed or when the value is set on the observable.  One thing to look out for is firing multiple change events when this occurs.  A use case where this arises is a widget that fires change events when the value is set programmatically (e.g. Text.setText(...)).  In these use cases an 'updating' flag is normally employed.
 
# An observable should fire change events when the value changes if at all possible.  This means when the value changes in the object being observed or when the value is set on the observable.  One thing to look out for is firing multiple change events when this occurs.  A use case where this arises is a widget that fires change events when the value is set programmatically (e.g. Text.setText(...)).  In these use cases an 'updating' flag is normally employed.
# Not all observables fire change events.  An example of this is Control.setEnabled(...) in SWT.  If the object being observed doesn't fire change events when the value is set programmatically the observable cannot observe programmatic changes in the observed object.  In these use cases it still pays to have the abstraction for get/set value but when coding against such observables it's good to be aware of this behavior.  Because of this it's good to always set the value on the observable to ensure that change events are fired.
+
# Not all observables fire change events when the state of its underlying object changes, but they do fire a change event if the change goes through the observable's setter.  An example of this is Control.setEnabled(...) in SWT.  If the object being observed doesn't fire change events when the value is set programmatically the observable cannot observe programmatic changes in the observed object.  In these use cases it still pays to have the abstraction for get/set value but when coding against such observables it's good to be aware of this behavior.  Because of this it's good to always set the value on the observable to ensure that change events are fired.
 
# In an observable when retrieving the value always retrieve it from the observed object. Don't cache the value in the observable if possible.  Caching can cause issues if there's potential for this state to get out of sync like in the Control.setEnabled(...) use case mentioned above.
 
# In an observable when retrieving the value always retrieve it from the observed object. Don't cache the value in the observable if possible.  Caching can cause issues if there's potential for this state to get out of sync like in the Control.setEnabled(...) use case mentioned above.
# If the observable is an <code>IObservableValue</code> and the type of the attribute is a primitive use the primitive class (e.g. Boolean.TYPE or boolean.class) rather than the boxed type (e.g. Boolean.class) even though when get/setValue(...) is inoked the boxed type will be returned.  By using the primitive the observable will be able to convey that the value cannot be null.  This allows for better control in the validation and conversion phases of binding.
+
# If the observable is an <code>IObservableValue</code> and the type of the attribute is a primitive use the primitive class (e.g. Boolean.TYPE or boolean.class) rather than the boxed type (e.g. Boolean.class) even though when get/setValue(...) is invoked the boxed type will be returned.  By using the primitive the observable will be able to convey that the value cannot be null.  This allows for better control in the validation and conversion phases of binding.
 +
 
 +
== @See ==
 +
[[Realm]] for how observables can be accessed in a multi-threaded environment.
 +
 
 +
[[Category:Data Binding]]

Latest revision as of 20:19, 5 September 2007

Observables are one of the key abstractions provided by JFace Data Binding and are an implementation of the Observer pattern. They provide a common abstraction for observing changes in objects.

JFace Data Binding
Home
How to Contribute
FAQ
Snippets
Concepts
Binding
Converter
Observable
Realm

[edit] Core Interfaces of Interest

  • IObservable - super-interface of all observables, allows to listen for generic change events
  • IObservableValue - has getValue(), setValue(), and allows to listen for value change events
  • IVetoableValue - inherits from IObservableValue, and allows to listen for before-change events
  • IObservableCollection - extends java.util.Collection and IObservable
  • IObservableList - extends java.util.List and IObservableCollection, and allows to listen for incremental list change events
  • IObservableSet - extends java.util.Set and IObservableCollection, and allows to listen for incremental set change events
  • IObservableMap - extends java.util.Map and IObservable, and allows to listen for incremental map change events

[edit] Implementation Design Principles

  1. An observable must remove listeners on the observed when disposed. For example if you registered selection listeners on a widget when the observable was constructed it must remove these on dispose of the observable.
  2. An observable should fire change events when the value changes if at all possible. This means when the value changes in the object being observed or when the value is set on the observable. One thing to look out for is firing multiple change events when this occurs. A use case where this arises is a widget that fires change events when the value is set programmatically (e.g. Text.setText(...)). In these use cases an 'updating' flag is normally employed.
  3. Not all observables fire change events when the state of its underlying object changes, but they do fire a change event if the change goes through the observable's setter. An example of this is Control.setEnabled(...) in SWT. If the object being observed doesn't fire change events when the value is set programmatically the observable cannot observe programmatic changes in the observed object. In these use cases it still pays to have the abstraction for get/set value but when coding against such observables it's good to be aware of this behavior. Because of this it's good to always set the value on the observable to ensure that change events are fired.
  4. In an observable when retrieving the value always retrieve it from the observed object. Don't cache the value in the observable if possible. Caching can cause issues if there's potential for this state to get out of sync like in the Control.setEnabled(...) use case mentioned above.
  5. If the observable is an IObservableValue and the type of the attribute is a primitive use the primitive class (e.g. Boolean.TYPE or boolean.class) rather than the boxed type (e.g. Boolean.class) even though when get/setValue(...) is invoked the boxed type will be returned. By using the primitive the observable will be able to convey that the value cannot be null. This allows for better control in the validation and conversion phases of binding.

[edit] @See

Realm for how observables can be accessed in a multi-threaded environment.