|
Evaluating Software Design Patterns — the "Gang of Four" patterns implemented in Java 6 |
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object dk.rode.thesis.meta.model.AbstractSequence<E> dk.rode.thesis.observer.SequenceObserversSequence<E,A>
E
- The type of values delivered by this sequence.A
- The type of the aspect used by this sequence.@Participant(value={"Subject","Observer"}) public abstract class SequenceObserversSequence<E,A>
A sequence observers sequence implements the basic
traits of any observable
sequence
that uses a sequence observer
as
the notification mechanism.
The observable
sequence
functionality is fully implemented by this class! Sub-classes
need simply implement the doNext()
method
(as opposed to next()
) without worrying about
notifying observers. Observers will be notified if the
getAspect()
method return a non-null aspect
value. It is invoked immediately after doNext()
.
This sequence is not thread-safe! It does not enforce synchronisation, neither when adding or removing observers, nor when observers are notified. It could be potentially dangerous or least time consuming to notify observers from a synchronised context, holding a lock on the sequence itself. If synchronisation is required, the context using the sequence must enforce it.
Implementation notes:
Observable sequences inheriting this class are double as an observer:
observable sequence A
can add observable sequence B
as
an observer. The notification of observers is thus
composite in a depth-first manner.
This class applies the Template Method
pattern: next()
is the template method, while doNext()
and
getAspect()
are primitive operations. This ensures consistent state
during notification.
Nested Class Summary |
---|
Nested classes/interfaces inherited from interface dk.rode.thesis.meta.model.Sequence |
---|
Sequence.State |
Field Summary | |
---|---|
private Map<SequenceObserver<A>,Set<A>> |
observers
A set containing the current added observers and their associated
aspects they subscribe to. |
Fields inherited from class dk.rode.thesis.meta.model.AbstractSequence |
---|
state |
Constructor Summary | |
---|---|
protected |
SequenceObserversSequence()
Sub-class no-arg constructor. |
protected |
SequenceObserversSequence(AspectObservableSequence<SequenceObserver<A>,A,E> sequence)
Copy constructor. |
Method Summary | |
---|---|
boolean |
addObserver(SequenceObserver<A> observer)
Adds the observer supplied as observer to this observable,
if not already. |
boolean |
addObserver(SequenceObserver<A> observer,
A aspect)
Adds the observer supplied as observer to this observable for
the aspect supplied as aspect , if not already. |
protected abstract E |
doNext()
Hook for sub-classes to perform the actual next()
operation without notifying observers. |
protected abstract A |
getAspect()
Hook for sub-classes to deliver the changed aspect value to notify observers about immediately after doNext() has been
invoked, if any. |
Set<A> |
getAspects(SequenceObserver<A> observer)
Returns a read-only set of the aspects the observer supplied as observer subscribes to in this observable, if any. |
Collection<SequenceObserver<A>> |
getObservers()
Returns the observers currently associated with this observable sequence. |
Collection<SequenceObserver<A>> |
getObservers(A aspect)
Returns the observers subscribed to the aspect supplied as aspect
in this observable. |
E |
next()
Returns the next element from this sequence. |
boolean |
removeObserver(Object observer)
Removes the observer supplied as observer from this
observable, if already added. |
boolean |
removeObserver(Object observer,
A aspect)
Removes the observer supplied as observer from this
observable with regards to the aspect supplied as aspect ,
if already added to it. |
void |
sequenceEvent(Sequence<?> sequence,
A aspect)
Notification method that is invoked when the sequence supplied as sequence
has changed its state to state . |
Methods inherited from class dk.rode.thesis.meta.model.AbstractSequence |
---|
getStringablePolicy, reset, state, toString, toString |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Methods inherited from interface dk.rode.thesis.meta.model.Sequence |
---|
bounded, consistent, copy, current, reset, state, unique |
Methods inherited from interface dk.rode.thesis.strategy.Stringable |
---|
getStringablePolicy, toString |
Field Detail |
---|
private final Map<SequenceObserver<A>,Set<A>> observers
observers
and their associated
aspects they subscribe to. If the associated set contains null, the observer subscribes to all aspect values.
Never null, but may be empty.
Constructor Detail |
---|
protected SequenceObserversSequence()
protected SequenceObserversSequence(AspectObservableSequence<SequenceObserver<A>,A,E> sequence)
sequence
- The observable sequence to copy; cannot be null.
NullPointerException
- If sequence
is null.Method Detail |
---|
public boolean addObserver(@Participant(value="ConcreteObserver") SequenceObserver<A> observer)
Observable
observer
to this observable,
if not already.
addObserver
in interface Observable<SequenceObserver<A>>
observer
- The observer to add; cannot be null.
observer
was added, false if not.Observable.removeObserver(Object)
public boolean addObserver(@Participant(value="ConcreteObserver") SequenceObserver<A> observer, A aspect)
AspectObservable
observer
to this observable for
the aspect supplied as aspect
, if not already.
If aspect
is null, observer
will be subscribed
to all possible aspect values.
addObserver
in interface AspectObservable<SequenceObserver<A>,A>
observer
- The observer to add; cannot be null.aspect
- The aspect to subscribe to; null means all.
observer
was added, false if not.AspectObservable.removeObserver(Object, Object)
protected abstract E doNext()
next()
operation without notifying observers.
protected abstract A getAspect()
doNext()
has been
invoked, if any. If this method returns null, no notification is performed as the aspect has not changed.
public Set<A> getAspects(SequenceObserver<A> observer)
AspectObservable
observer
subscribes to in this observable, if any.
getAspects
in interface AspectObservable<SequenceObserver<A>,A>
observer
- The observer; cannot be null.
public Collection<SequenceObserver<A>> getObservers()
Observable
No specific order is maintained.
Modifying the returned collection will not affect this observable.
getObservers
in interface Observable<SequenceObserver<A>>
public Collection<SequenceObserver<A>> getObservers(A aspect)
AspectObservable
aspect
in this observable.
getObservers
in interface AspectObservable<SequenceObserver<A>,A>
aspect
- The aspect; null means all.
aspect
;
never null, but can be empty.public final E next()
Observers associated with this observable sequence are notified
with the (new) aspect of this sequence if getAspect()
returns a non-null value.
next
in interface Sequence<E>
doNext()
,
getAspect()
,
sequenceEvent(Sequence, Object)
public boolean removeObserver(Object observer)
Observable
observer
from this
observable, if already added. Trying to remove an observer that is not associated with this observable has no effect.
removeObserver
in interface Observable<SequenceObserver<A>>
observer
- The observer to remove; cannot be null.
observer
was removed, false if not.Observable.addObserver(Object)
public boolean removeObserver(Object observer, A aspect)
AspectObservable
observer
from this
observable with regards to the aspect supplied as aspect
,
if already added to it. Trying to remove an observer that is not associated with this observable or to an unsubscribed aspect has no effect.
removeObserver
in interface AspectObservable<SequenceObserver<A>,A>
observer
- The observer to remove for aspect
; cannot be null.aspect
- The aspect in question; null means all.
observer
was removed from the subscription
to aspect
(or all if null), false if not.AspectObservable.addObserver(Object, Object)
public void sequenceEvent(Sequence<?> sequence, A aspect)
SequenceObserver
sequence
supplied as sequence
has changed its state to state
.
The type of sequence is not defined; it cannot be assumed
observable
, or even of the type
this observer was attached to; it might be adapted, decorated,
composite, or proxied.
sequenceEvent
in interface SequenceObserver<A>
sequence
- This sequence; cannot be null.aspect
- The current (new) aspect; cannot be null.
|
Gunni Rode / rode.dk | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |