Evaluating Software Design Patterns
— the "Gang of Four" patterns implemented in Java 6

dk.rode.thesis.observer
Class AnnotatedObserversSequence<E>

java.lang.Object
  extended by dk.rode.thesis.meta.model.AbstractSequence<E>
      extended by dk.rode.thesis.observer.AnnotatedObserversSequence<E>
Type Parameters:
E - The type of values delivered by this sequence.
All Implemented Interfaces:
Sequence<E>, Observable<Object>, ObservableSequence<Object,Sequence.State,E>, SequenceObserver<Sequence.State>, Copyable<Sequence<E>>, StrictCopyable<Sequence<E>>, Stringable<Sequence<E>>
Direct Known Subclasses:
AnnotatedObserversSequenceDecorator

@Participant(value="Subject")
public abstract class AnnotatedObserversSequence<E>
extends AbstractSequence<E>
implements ObservableSequence<Object,Sequence.State,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.

The context type must furthermore be a type this sequence type is assignable to (default), or an explicit type supplied at construction time.

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.

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:
This sequence uses an ObserverManager internally to handle the observer functionality.

An observer can be notified any method accepting a Sequence as the first argument and a Sequence.State type as the second. This corresponds to the notification method defined in the SequenceObserver interface, but could easily have been different by supplying different formal parameter types to the ObserverManager used. This class applies the Template Method pattern: next() is the template method, and doNext() is a primitive operation. This ensures consistent state during notification.

Author:
Gunni Rode / rode.dk
See Also:
ObserverManager, Executor

Nested Class Summary
 
Nested classes/interfaces inherited from interface dk.rode.thesis.meta.model.Sequence
Sequence.State
 
Field Summary
private  ObserverManager observers
          The observer manager storing the observers.
 
Fields inherited from class dk.rode.thesis.meta.model.AbstractSequence
state
 
Constructor Summary
protected AnnotatedObserversSequence()
          No-arg sub-class constructor.
  AnnotatedObserversSequence(AnnotatedObserversSequence<E> sequence)
          Copy constructor.
protected AnnotatedObserversSequence(Class<?> ownerType)
          Sub-class constructor.
 
Method Summary
 boolean addObserver(Object object)
          Adds the observer supplied as observer to this observable, if not already.
protected abstract  E doNext()
          Hook for sub-classes to perform the actual next() operation without notifying observers.
 Collection<Object> getObservers()
          Returns the observers currently associated with this observable sequence.
 E next()
          Returns the next element from this sequence.
 boolean removeObserver(Object object)
          Removes the observer supplied as observer from this observable, if already added.
 void sequenceEvent(Sequence<?> sequence, Sequence.State state)
          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

observers

private final ObserverManager observers
The observer manager storing the observers.

Never null.

Constructor Detail

AnnotatedObserversSequence

protected AnnotatedObserversSequence()
No-arg sub-class constructor.

The context type of the Executor annotations must be assignable to the type of this sequence in order to be accepted as notification methods by this observable sequence.

See Also:
ObserverManager.getOwnerType()

AnnotatedObserversSequence

public AnnotatedObserversSequence(AnnotatedObserversSequence<E> sequence)
Copy constructor.

Parameters:
sequence - The observable sequence to copy; cannot be null.
Throws:
NullPointerException - If sequence is null.

AnnotatedObserversSequence

protected AnnotatedObserversSequence(Class<?> ownerType)
Sub-class constructor.

The context type of the Executor annotations must be assignable to the type supplied as ownerType in order to be accepted as notification methods by this observable sequence.

Parameters:
ownerType - The type to use; can be null, in which case the type of this sequence is used.
See Also:
ObserverManager.getOwnerType()
Method Detail

addObserver

public boolean addObserver(@Participant(value="ConcreteObserver")
                           Object object)
Description copied from interface: Observable
Adds the observer supplied as observer to this observable, if not already.

Specified by:
addObserver in interface Observable<Object>
Parameters:
object - The observer to add; cannot be null.
Returns:
True if observer was added, false if not.
See Also:
Observable.removeObserver(Object)

doNext

protected abstract E doNext()
Hook for sub-classes to perform the actual next() operation without notifying observers.

Returns:
The next element; never null.

getObservers

public Collection<Object> getObservers()
Description copied from interface: Observable
Returns the observers currently associated with this observable sequence.

No specific order is maintained.

Modifying the returned collection will not affect this observable.

Specified by:
getObservers in interface Observable<Object>
Returns:
The collection of observers; never null, but can be empty.

next

public final E next()
Returns the next element from this sequence.

Observers associated with this observable sequence are notified with the (new) state of this sequence.

Specified by:
next in interface Sequence<E>
Returns:
The next element; never null.
See Also:
sequenceEvent(Sequence, Sequence.State)

removeObserver

public boolean removeObserver(Object object)
Description copied from interface: Observable
Removes the observer supplied as observer from this observable, if already added.

Trying to remove an observer that is not associated with this observable has no effect.

Specified by:
removeObserver in interface Observable<Object>
Parameters:
object - The observer to remove; cannot be null.
Returns:
True if observer was removed, false if not.
See Also:
Observable.addObserver(Object)

sequenceEvent

public void sequenceEvent(Sequence<?> sequence,
                          Sequence.State state)
Description copied from interface: SequenceObserver
Notification method that is invoked when the 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.

Specified by:
sequenceEvent in interface SequenceObserver<Sequence.State>
Parameters:
sequence - This sequence; cannot be null.
state - The current (new) aspect; cannot be null.

Gunni Rode / rode.dk

Feel free to use and/or modify the Java 6 source code developed for this thesis AT YOUR OWN RISK, but note that the source code comes WITHOUT ANY — and I do mean WITHOUT ANY — form of warranty WHAT SO EVER!

The original thesis and source code are available at rode.dk/thesis.