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

dk.rode.thesis.memento
Class RangeSequence

java.lang.Object
  extended by dk.rode.thesis.meta.model.AbstractSequence<Integer>
      extended by dk.rode.thesis.memento.RangeSequence
All Implemented Interfaces:
MemorizableSequence<Integer>, ReversibleSequence<Integer>, Sequence<Integer>, Copyable<Sequence<Integer>>, StrictCopyable<Sequence<Integer>>, Stringable<Sequence<Integer>>, Serializable

@Participant(value="Originator")
public class RangeSequence
extends AbstractSequence<Integer>
implements ReversibleSequence<Integer>, Serializable, MemorizableSequence<Integer>

A range sequence represents a positive Integer value that is increased with each call to next(), which can be reversed to deliver previous values as well unless unbounded.

A start value can be supplied (default is zero), and an integer sequence can also be found by supplying an end value. Default range sequences are unbounded.

It can have its state restored either by using the Java Serialization mechanism, or by explicitly using mementos.

A range sequence may be bounded, but is consistent and unique.

Implementation notes:
The mementos created are GuardedSequenceMemento instances. However, regular mementos can still be set. This could easily be remedied by an instanceof check, though.

Author:
Gunni Rode / rode.dk
See Also:
Serialized Form

Nested Class Summary
 
Nested classes/interfaces inherited from interface dk.rode.thesis.meta.model.Sequence
Sequence.State
 
Field Summary
private  boolean direction
          True to return the next higher sequence value ("forward"), false to return previous values ("reverse")
private  int end
          End number of this sequence.
private  int sequence
          The current sequence number.
(package private) static long serialVersionUID
          The serial version.
private  int start
          Start number of this sequence.
 
Fields inherited from class dk.rode.thesis.meta.model.AbstractSequence
state
 
Constructor Summary
RangeSequence()
          No-arg constructor.
RangeSequence(int start)
          Constructor.
RangeSequence(int start, int end)
          Constructor.
RangeSequence(RangeSequence sequence)
          Copy constructor.
 
Method Summary
 boolean bounded()
          If an end value was supplied at construction time, this sequence is bounded, and true is returned.
 boolean consistent()
          Returns true.
 RangeSequence copy()
          Returns a copy of this reversible sequence that will start at the same sequence index as this sequence in the same direction.
 Integer current()
          Returns the current element from this sequence.
 SequenceMemento<Integer> getMemorizableState()
          Returns a sequence memento representing the current state of this sequence.
 Integer next()
          Returns the next element from this sequence.
private  void readObject(ObjectInputStream in)
          Deserializes this memorizable sequence.
 void reset()
          Resets this sequence to start over if it is consistent.
 Integer reverse()
          Reverses this reversible sequence, if currently reversible.
 boolean reversible()
          Returns true if this range sequence is bounded, false otherwise.
 void setMemorizableState(SequenceMemento<Integer> memento)
          Updates this sequence to the state supplied as memento.
 boolean unique()
          Returns true.
private static void validate(int start, int end)
          Validates the start and end values supplied as start and end, respectively.
private  void writeObject(ObjectOutputStream out)
          Serializes this memorizable range sequence.
 
Methods inherited from class dk.rode.thesis.meta.model.AbstractSequence
getStringablePolicy, 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
state
 
Methods inherited from interface dk.rode.thesis.strategy.Stringable
getStringablePolicy, toString
 

Field Detail

direction

private boolean direction
True to return the next higher sequence value ("forward"), false to return previous values ("reverse")


end

private int end
End number of this sequence.

Invariant: end >= start >= 0


sequence

private int sequence
The current sequence number.

Invariant: start <= sequence <= end


serialVersionUID

static final long serialVersionUID
The serial version.

See Also:
Constant Field Values

start

private int start
Start number of this sequence.

Invariant: start >= 0

Constructor Detail

RangeSequence

public RangeSequence()
No-arg constructor.

This sequence starts at 0 and is unbound, i.e. infinite.


RangeSequence

public RangeSequence(int start)
Constructor. This sequence starts at start and is unbound, i.e. infinite.

Parameters:
start - The start value of this sequence; must be >= 0.
Throws:
IllegalArgumentException - If start is negative.

RangeSequence

public RangeSequence(int start,
                     int end)
Constructor. This sequence starts at start and ends at end. This sequence is thus bounded.

Parameters:
start - The start value of this sequence; must be >= 0.
end - The end value of this sequence; must be >= start.
Throws:
IllegalArgumentException - If start is negative, or if end is smaller than start.

RangeSequence

public RangeSequence(RangeSequence sequence)
Copy constructor.

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

bounded

public boolean bounded()
If an end value was supplied at construction time, this sequence is bounded, and true is returned. Otherwise false.

Specified by:
bounded in interface Sequence<Integer>
Returns:
True if bounded, false if not.
See Also:
Sequence.unique()

consistent

public boolean consistent()
Returns true.

Specified by:
consistent in interface Sequence<Integer>
Returns:
True.

copy

public RangeSequence copy()
Description copied from interface: ReversibleSequence
Returns a copy of this reversible sequence that will start at the same sequence index as this sequence in the same direction.

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

current

public Integer current()
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<Integer>
Returns:
The current element; never null.

getMemorizableState

public SequenceMemento<Integer> getMemorizableState()
Description copied from interface: MemorizableSequence
Returns a sequence memento representing the current state of this sequence.

Specified by:
getMemorizableState in interface MemorizableSequence<Integer>
Returns:
The memento; never null.

next

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

Specified by:
next in interface Sequence<Integer>
Returns:
The next element; never null.
See Also:
Sequence.current(), Sequence.state()

readObject

private void readObject(ObjectInputStream in)
                 throws IOException,
                        ClassNotFoundException
Deserializes this memorizable sequence.

To protect against malicious attacks, all read attributes are validated.

Parameters:
in - The input stream to read from; never null.
Throws:
IOException - In case the deserialization fails.
ClassNotFoundException - If this class could not be loaded.
See Also:
validate(int, int)

reset

public void reset()
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<Integer>
Overrides:
reset in class AbstractSequence<Integer>

reverse

public Integer reverse()
Description copied from interface: ReversibleSequence
Reverses this reversible sequence, if currently reversible.

The current value is not affected by this method, and is returned by this method.

Specified by:
reverse in interface ReversibleSequence<Integer>
Returns:
The current sequence value; never null.
Throws:
IllegalStateException - If this sequence cannot be reversed at this point.

reversible

public boolean reversible()
Returns true if this range sequence is bounded, false otherwise.

Specified by:
reversible in interface ReversibleSequence<Integer>
Returns:
True if bounded, ergo reversible, false if not.

setMemorizableState

public void setMemorizableState(SequenceMemento<Integer> memento)
                         throws MemorizableException
Description copied from interface: MemorizableSequence
Updates this sequence to the state supplied as memento.

Specified by:
setMemorizableState in interface MemorizableSequence<Integer>
Parameters:
memento - The memento supplying the state; cannot be null.
Throws:
MemorizableException - If the update fails, e.g. illegal memento state for this sequence, or illegal memento type.

unique

public boolean unique()
Returns true.

Specified by:
unique in interface Sequence<Integer>
Returns:
True.
See Also:
Sequence.consistent()

validate

private static void validate(int start,
                             int end)
Validates the start and end values supplied as start and end, respectively.

Returns silently upon success, or throws an exception otherwise.

Parameters:
start - The start value; must be >= 0.
end - The end value; must be >= start if not infinite.
Throws:
IllegalArgumentException - If start is negative, or if end is smaller than start.
See Also:
RangeSequence(int, int), readObject(ObjectInputStream)

writeObject

private void writeObject(ObjectOutputStream out)
                  throws IOException
Serializes this memorizable range sequence.

The internal state is also serialized.

Parameters:
out - The output stream to write to; never null.
Throws:
IOException - In case the serialization fails.

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.