|
Evaluating Software Design Patterns — the "Gang of Four" patterns implemented in Java 6 |
||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | ||||||||
See:
Description
| Interface Summary | |
|---|---|
| AspectObservable<O,A> | An aspect observable object is an object that has a collection of associated observers to be notified in case the object changes its internal state, or aspect, and where the observers can subscribe certain aspects only. |
| AspectObservableSequence<O,A,E> | An aspect observable sequence is a sequence that allows for
observers of the type supplied as the type parameter
O to subscribe to specific sequence aspect values and
be notified when the sequence changes its aspect to such a
value. |
| Observable<O> | An observable object is an object that has a collection of associated observers to be notified in case the object changes its internal state, or aspect. |
| ObservableSequence<O,A,E> | An observable sequence is a sequence that allows for
observers of the type supplied as the type parameter
O to be notified when the sequence changes its aspect. |
| SequenceObserver<A> | A sequence observer is an object that is
notified
when the observable sequence
it is attached to changes its aspect value. |
| Class Summary | |
|---|---|
| AnnotatedObserversSequence<E> | An annotated observers sequence implements the basic
traits of any observable sequence
that uses the Executor annotation to identify notification
methods for observers that accepts a Sequence type as the
first argument and a Sequence.State
type as the second. |
| AnnotatedObserversSequenceDecorator<E> | An annotated observers sequence decorator decorates
any Sequence to become an observable
sequence that uses the Executor annotation to identify notification
methods for observers that accepts a Sequence type as the
first argument and a Sequence.State
type as the second. |
| BirthdayRegistry | A birthday registry is a simple application that stores the name and date of birth of people registered to it. |
| CorrelatedSequenceObserver | A correlated sequence observer correlates the behaviour
of an observable sequence with another
(perhaps observable) Sequence. |
| DateSequence | An observable date sequence is a sequence that will
advance an initial date by one day each time next() is
invoked and then notify relevant observers
of its state changes. |
| Main | Observer tests. |
| ObserverManager | An observer manager is a stand-alone manager storing
any type of observer that will be notified with methods
declared in its class that are annotated with a matching
Executor annotation. |
| PrintSequenceObserver | A print sequence observer prints the state of any
observable sequence it is
observing. |
| ProbeSequenceObserver | A probe sequence observer prints the internal attributes that
has changed for a given sequence since the last time
the observer was notified about that sequence, based on equality
using equals(Object) (and hashCode()). |
| SequenceObserversSequence<E,A> | A sequence observers sequence implements the basic
traits of any observable sequence
that uses a sequence observer as
the notification mechanism. |
| SequenceObserversSequenceDecorator<E,A> | A sequence observers sequence decorator decorates any
sequence to become an observable sequence that uses a sequence
observer as the notification mechanism. |
| Enum Summary | |
|---|---|
| ObserverManager.NotificationPolicy | Default error handlers for observer registries. |
Implementations and examples of the Observer design pattern [Gamma95, p.293].
Intent:
Define a one—to—many dependency between objects so that when one object changes state, all dependants are notified and updated automatically.
Observable interface. The
Observable interface only defines methods for
adding, removing, and fetching observers,
but no a method to notify the observers. The
type of observers must also be specified by a type parameter.
All this is left up to the actual implementations, because
different implementations will have different needs to the type of
notification performed, for example in the type of arguments
used, the notification order, asynchronous notification, etc.
The AspectObservable type extends
Observable to allow observers to subscribe to specific
aspects only.
A refinement of the Observable interface is the
ObservableSequence
type, which represents a Sequence
that will notify observers when its internal
aspect changes, typically when its internal
state has changed.
The AspectObservableSequence sub-type
allows observers to sub-scribe to specific aspects only, i.e. to
specific internal state values only.
For observable sequences, the Observer participant is
partly represented by the SequenceObserver
interface, which defines the notification method to use.
As a feature, ObserverableSequence
extends SequenceObserver, and thus uses the inherited
notification method to notify its observers. If the actual
ObservableSequence at the same time chooses to
use SequenceObserver as the observer type, the
notification method is used to both issue and
receive notifications. This makes the observable
composite.
However, observers need not be related to sequences, nor be required
to use the SequenceObserver interface. As an alternative,
any object annotated with the Executor
annotation may be considered a representative of the Observer
participant under certain conditions (see implementation notes below).
Two abstract sub-classes of the ObservableSequence interface
have been defined as well, also representing the Subject
participant, namely the SequenceObserversSequence
and AnnotatedObserversSequence classes.
The first represents an observable sequence that uses
SequenceObserver types as observers, while the latter represents
an observable sequence that uses annotated objects as observers.
The ConcreteSubject participant is represented by any
non-abstract implementation of the Observable interface. The
DateSequence class is an observable
sequence inheriting SequenceObserversSequence, while the
ObserverManager class is a stand-alone
observer manager storing annotated objects as observers; it is not
specifically related to sequences and the changed subjects are supplied
as arguments to the notification method (Change Manager). A
specific implementation of the AnnotatedObserversSequence
class have been made in form of the
AnnotatedObserversSequenceDecorator
class that can be used to make any sequence observable using annotated
objects as observers.
The CorrelatedSequenceObserver,
PrintSequenceObserver,
ProbeSequenceObserver,
and BirthdayRegistry
classes all represent the ConcreteObserver participant.
All except ProbeSequenceObserver implements the
SequenceObserver interface. The latter uses annotations and
so does the PrintSequenceObserver class. The
PrintSequenceObserver can thus be used as an observer for
both abstract sub-classes of ObserverableSequence.
Implementation notes:
The AnnotatedObserversSequence class
internally uses a ObserverManager
via object composition. Annotated observers works by annotating one or
more methods in a given observer class - regardless of visibility, name,
and if static - with the Executor
annotation. However, the formal parameter types of the methods must
match those supplied at construction time to the
AnnotatedObserversSequence instance used (and thus to the
ObserverManager used). At notification time, corresponding
arguments must then supplied to the notification method that reflectively
will invoke each annotated method.
The BirthdayRegistry class uses an inner class to implement
the observer functionality, which ensures that we do not expose the
SequenceObserver interface for misuse.
This is common practice in Java. However, since the inner class is in
effect an adapter, the exact type
of notification mechanism used by the observable sequence must
be known. For the birthday registry, the SequenceObserver
interface is used, and this limits the type of applicable observable
sequences to SequenceObserver<SequenceObserver,Date>.
As a curiosity, Java provides the java.util.Observable
and java.util.Observer classes to support the
Observer pattern, and has done so since version 1.0 or so. To our knowledge,
these classes are rarely used. The interface they provide seems far from
adequate, and most methods are synchronised. Internally a
java.util.Vector is even used, practically
deprecated since version 1.2!
|
Gunni Rode / rode.dk | ||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES | ||||||||