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

dk.rode.thesis.bridge
Class SequenceAbstraction<E>

java.lang.Object
  extended by dk.rode.thesis.meta.model.AbstractSequence<E>
      extended by dk.rode.thesis.bridge.SequenceAbstraction<E>
Type Parameters:
E - The type of values delivered by this sequence. Note that the values used by this sequence may generate any type S that satisfies <S extends E>.
All Implemented Interfaces:
Sequence<E>, Copyable<Sequence<E>>, StrictCopyable<Sequence<E>>, Stringable<Sequence<E>>
Direct Known Subclasses:
MemorizableSequenceAbstraction, SynchronisedSequenceAbstraction

@Participant(value="Abstraction")
public class SequenceAbstraction<E>
extends AbstractSequence<E>
implements Sequence<E>

A sequence abstraction defers the creation of sequence values to a value generator.

The generator to use can either be supplied at construction time, or any time before sequence use via the setGenerator(SequenceValueGenerator) method. Any sequence method expect copy and setGenerator will throw an IllegalStateException if accessed before a generator has been set! The toString(StringablePolicy) method will only fail in case the methods described above is used by the specified SequencePolicy.

The size, ordered, and duplicate properties of a SequenceValueGenerator makes it very easy to alter the behaviour of a given sequence abstraction!

Implementation notes:
The separation between the abstraction and implementation allows the abstraction to use any kind of implementation that delivers a sub-type of the value delivered by the sequence. Here, the implementation is only allowed to be set once, because changing a sequence while traversing it seems illogical, but other Bridge implementations may benefit from changing the implementation even after the abstraction is in use.

Author:
Gunni Rode / rode.dk

Nested Class Summary
 
Nested classes/interfaces inherited from interface dk.rode.thesis.meta.model.Sequence
Sequence.State
 
Field Summary
protected  E current
          The current sequence value.
protected  SequenceValueGenerator<? extends E> generator
          The generator used to generate the next sequence value on an invocation of next().
 
Fields inherited from class dk.rode.thesis.meta.model.AbstractSequence
state
 
Constructor Summary
SequenceAbstraction()
          Constructor.
SequenceAbstraction(SequenceAbstraction<E> sequence)
          Copy constructor.
SequenceAbstraction(SequenceValueGenerator<? extends E> generator)
          Constructor, which creates this sequence abstraction to use the value generator supplied as generator.
 
Method Summary
 boolean bounded()
          Returns true if this sequence is bounded, i.e.
 boolean consistent()
          Returns true if this sequence is consistent, i.e. deliver the same values, in order, after restart or reset.
 SequenceAbstraction<E> copy()
          Returns a copy of this sequence that will start at the same sequence index as this sequence.
 E current()
          Returns the current element from this sequence.
 boolean isInitialised()
          Returns true if a generator has been set for this sequence abstraction, false if not.
 E next()
          Returns the next element from this sequence.
 void reset()
          Resets this sequence to start over if it is consistent.
 SequenceAbstraction<E> setGenerator(SequenceValueGenerator<? extends E> generator)
          Sets the generator to use for this sequence to generator.
 Sequence.State state()
          Returns the internal state of this sequence.
 CharSequence toString(StringablePolicy<? super Sequence<E>> policy)
          Returns a char sequence representation of this stringable object using the format determined by policy or the default policy in case policy is null.
 boolean unique()
          Returns true if this sequence deliver a given sequence value at most one time until reset or restarted.
 
Methods inherited from class dk.rode.thesis.meta.model.AbstractSequence
getStringablePolicy, 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.strategy.Stringable
getStringablePolicy
 

Field Detail

current

protected E current
The current sequence value.

Never null if this sequence has had a generator set.


generator

@Participant(value="Implementation")
protected SequenceValueGenerator<? extends E> generator
The generator used to generate the next sequence value on an invocation of next().

Supplied either at construction time, or set explicitly using the setGenerator(SequenceValueGenerator) method. Can be set at most once, i.e. the generator cannot change once set, but must be set before this sequence is valid and can be used.

Never empty, and never null for all practical purposes.

Constructor Detail

SequenceAbstraction

public SequenceAbstraction()
Constructor.

A value generator must explicitly be set using the setGenerator(SequenceValueGenerator) method before this sequence is valid!


SequenceAbstraction

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

If sequence does not have a value generator set, a generator must explicitly be set for this sequence using the setGenerator(SequenceValueGenerator) method before this sequence is valid!

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

SequenceAbstraction

public SequenceAbstraction(@Participant(value="Implementation")
                           SequenceValueGenerator<? extends E> generator)
Constructor, which creates this sequence abstraction to use the value generator supplied as generator.

The setGenerator(SequenceValueGenerator) must not be invoked for this sequence.

Parameters:
generator - The generator to use; cannot be null.
Throws:
NullPointerException - If generator is null.
Method Detail

bounded

public final boolean bounded()
                      throws IllegalStateException
Description copied from interface: Sequence
Returns true if this sequence is bounded, i.e. deliver values between the initial sequence value and some upper bound.

The same type of sequence may represent both bounded and unbounded sequences and the behaviour is determined and fixed at construction time. Bounded sequences will restart if they deliver consistent values.

Specified by:
bounded in interface Sequence<E>
Returns:
True if bounded, false if not.
Throws:
IllegalStateException - If a generator has not been set.
See Also:
Sequence.unique()

consistent

public final boolean consistent()
                         throws IllegalStateException
Description copied from interface: Sequence
Returns true if this sequence is consistent, i.e. deliver the same values, in order, after restart or reset.

Only bounded consistent sequences will restart. Consistent sequences need not deliver unique sequence values.

Instances of the same type of sequences are always consistent or inconsistent; it is determined at design time, not construction time.

Specified by:
consistent in interface Sequence<E>
Returns:
True if consistent, false if not.
Throws:
IllegalStateException - If a generator has not been set.

copy

public SequenceAbstraction<E> copy()
Description copied from interface: Sequence
Returns a copy of this sequence that will start at the same sequence index as this sequence.

Specified by:
copy in interface Sequence<E>
Specified by:
copy in interface Copyable<Sequence<E>>
Returns:
A copy of this sequence; never null.

current

public E current()
          throws IllegalStateException
Description copied from interface: Sequence
Returns the current element from this sequence.

This method can be invoked even if Sequence.next() has not been invoked yet, thus delivering the initial value of this sequence.

Specified by:
current in interface Sequence<E>
Returns:
The current element; never null.
Throws:
IllegalStateException - If a generator has not been set.

isInitialised

public boolean isInitialised()
Returns true if a generator has been set for this sequence abstraction, false if not.

If this sequence is not initialised, all sequence methods will throw an exception on use!

Returns:
True if initialised, false if not.

next

public E next()
       throws IllegalStateException
Description copied from interface: Sequence
Returns the next element from this sequence.

Specified by:
next in interface Sequence<E>
Returns:
The next element; never null.
Throws:
IllegalStateException - If a generator has not been set.
See Also:
Sequence.current(), Sequence.state()

reset

public void reset()
           throws IllegalStateException
Description copied from interface: Sequence
Resets this sequence to start over if it is consistent.

If this sequence is consistent, the sequence will restart.

Specified by:
reset in interface Sequence<E>
Overrides:
reset in class AbstractSequence<E>
Throws:
IllegalStateException - If a generator has not been set.

setGenerator

public SequenceAbstraction<E> setGenerator(@Participant(value="Implementation")
                                           SequenceValueGenerator<? extends E> generator)
                                    throws IllegalStateException
Sets the generator to use for this sequence to generator.

A generator can only be set once, and cannot be changed once set. This sequence is not valid until a generator has been set.

Parameters:
generator - The generator to use; cannot be null.
Returns:
This sequence abstraction; never null.
Throws:
NullPointerException - If generator is null.
IllegalStateException - If a generator has already been set.
See Also:
SequenceAbstraction(SequenceValueGenerator)

state

public Sequence.State state()
                     throws IllegalStateException
Description copied from interface: Sequence
Returns the internal state of this sequence.

Specified by:
state in interface Sequence<E>
Overrides:
state in class AbstractSequence<E>
Returns:
The internal state; never null.
Throws:
IllegalStateException - If a generator has not been set.

toString

public CharSequence toString(StringablePolicy<? super Sequence<E>> policy)
Description copied from interface: Stringable
Returns a char sequence representation of this stringable object using the format determined by policy or the default policy in case policy is null.

In Foo, a typical implementation of this method could be:

    public CharSequence toString(StringablePolicy<? super Foo> policy) {
      return this.getStringablePolicy(policy).toString(this);
    }
 
There are two approaches to formatting this stringable object into a char sequence representation:

  1. Let policy decide the entire format, as in the Foo example above; or

  2. Use policy to format part of the overall representation, for example letting this method append certain text regardless of the policy used.

Bullet 1) is not always applicable because a given policy implementation may not have access to all required information in its StringablePolicy.toString(Object) method, for example in case multiple stringable objects should be formatted into an overall representation.

In case an implementation uses the approach from bullet 2), care must be take to respect the policy hints so the overall format remains meaningful.

Specified by:
toString in interface Stringable<Sequence<E>>
Overrides:
toString in class AbstractSequence<E>
Parameters:
policy - The policy to dictate the formatting; can be null, in which case the result of toString method is returned.
Returns:
The char sequence representation; never null.
See Also:
StringablePolicy.Type

unique

public boolean unique()
               throws IllegalStateException
Description copied from interface: Sequence
Returns true if this sequence deliver a given sequence value at most one time until reset or restarted.

Unbounded sequences that are unique will never deliver the same sequence value more than once.

The same type of sequence may represent both unique and not unique sequences and the behaviour is determined and fixed at construction time.

Specified by:
unique in interface Sequence<E>
Returns:
True if unique, false if not.
Throws:
IllegalStateException - If a generator has not been set.
See Also:
Sequence.consistent()

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.