|
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 |