T
- the type of the value of this expressionpublic interface Expression<T>
An expression for use in reactive programming. An expression has a
value which can be resolved through the invocation of
getValue()
or decoupleValue()
.
This class is intended to be Observable
over a specific behavior: its
Observer
s should be notified any time the value which would be
resolved from the expression becomes different from the previously-resolved,
last-known value.
Any mechanism of synchronization, though a common concern, is left entirely to the discretion of implementations.
Note that the concept of an Expression
differs from the concept of a
ObservableValue
in that an expression is observable over itself,
rather than being observable over the value it represents. This is because
expressions are more typically intended to be lazily evaluated, and observers
directly over the value would cause eager evaluation. The methods
over(ObservableValue)
and over(Observable, Object)
are
provided to bridge the gap from Observable
to Expression
.
Modifier and Type | Method and Description |
---|---|
default AnonymousExpression<T> |
anonymize() |
default T |
decoupleValue() |
T |
getValue()
This should always return the correct current value for this Expression.
|
static <T> AnonymousExpression<T> |
immutable(T value)
Create an immutable
Expression instance whose value is always that
given, and upon which read locks are always available. |
Observable<Expression<? extends T>> |
invalidations() |
static <T> AnonymousExpression<T> |
over(Observable<T> changes,
T initialValue)
Provide an expression view over an observable value.
|
static <T> AnonymousExpression<T> |
over(ObservableValue<T> value)
Provide an expression view over an observable value.
|
Observable<Expression<? extends T>> invalidations()
T getValue()
Expression
, i.e. it should be either an immutable class, a const
reference, or a copy of the underlying value. This is important, but
conversely it does not mean that the return value can necessarily be
relied upon not to not mutate when this expression is updated, unless a read
lock is held.
Once a value has been returned, it is up to the implementing Expression as to
whether the value will be reliable such that it will remain the same even if
the conceptual value of this expression subsequently changes, or whether it
will update automatically with the expression. Please only rely on either
behavior if it is explicitly documented, otherwise use
decoupleValue()
if you need a persistent reference which is safe
to mutate and/or safe from external mutation.
The observers should only ever be notified of an update from the thread which
has the write lock on an Expression
, and Expression
s should
be careful to only notify observers when they are in a state where their
value can be fetched. Immediate fetch is discouraged, though. Expressions
should generally update lazily, not eagerly.
default T decoupleValue()
getValue()
at time
of invocation, with the added guarantee that it will not be further
mutated by this Expression
static <T> AnonymousExpression<T> immutable(T value)
Expression
instance whose value is always that
given, and upon which read locks are always available. Further, an observer
set is not maintained, as observers will never receive notifications, so
attempting to add or remove them will always return true
.T
- the type of the expressionvalue
- the value of the new immutable Expression
Expression
instance whose value is always that
given, and upon which read locks are always availablestatic <T> AnonymousExpression<T> over(Observable<T> changes, T initialValue)
changes
- the observable providing the value updatesinitialValue
- the initial expression valuestatic <T> AnonymousExpression<T> over(ObservableValue<T> value)
value
- the observable providing the initial value, and the value updatesdefault AnonymousExpression<T> anonymize()