|
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.meta.model.ArraySequence<String> dk.rode.thesis.singleton.SimpsonsFamilySequence
@Participant(value="Singleton") @Singleton(value="getFamily") public class SimpsonsFamilySequence
A Simpsons family sequence is a singleton sequence representing the primary family members in the one and only The Simpsons family.
Only a single instance of this class is created, on demand only, and
is available via the getFamily()
method. However, sub-classing
is allowed using the supplied sub-class
and/or copy
constructors. If any other context than a sub-class tries to invoke these
constructors, a SingletonError
is thrown! Hence, the singleton
invariant is still enforced even though sub-classing is allowed, and
sub-classes may or may not be singletons.
Implementation notes:
The SimpsonsFamilySequence
utilises a static inner class to store the
actual singleton instance. Unlike the DanishAlphabetSequence
class,
the instance is therefore not created at the class loading time, but
the first time getFamily()
is invoked, i.e. lazily initialised.
Therefore, for example, accessing the static field SIZE
will
not cause the singleton instance to be created. The initialisation
utilises standard static initialisation (of the inner class), and the
getFamily()
method need not be synchronised. This corresponds
to the initialise-on-demand holder class idiom [Bloch01, p.194].
The check to see if it is a sub-class that is invoking a
sub-class constructor is done using a Caller
instance.
It utilises Java's reflection capabilities. Acquiring a sub-class
instance before the getFamily()
method has been invoked
will not cause the singleton instance to be created. Sub-class
constructors are declared protected, but even if they had been public, the
sub-class check would still work. But, by declaring them protected, we only
have to worry about objects in the same package illegally invoking the
constructors. However, using reflection, even private members can be
accessed if the security manager allows it, but the sub-class check
will still work if reflection is used. There is furthermore a check
in the private constructor that ensures that SimpsonsFamilySequence
instances cannot be created using reflection (the same goes for the
other singleton types declared in this package!). The SimpsonsFamilySequence
class
is thus a Guarded Type.
Though not implemented, this class could implement java.io.Serializable
. If so, the serialization should override the serialization
methods writeReplace()
and readResolve()
, the latter always returning
the singleton instance. It does not implement java.lang.Cloneable
,
either (to throw an exception), because otherwise sub-classes cannot become cloneable.
It is ok for a sub-class to invoke super.clone()
because that will correspond
to Object.clone()
, which will return an instance of the sub-class, not
this sequence. This is illustrated in the MutatedSimpsonsFamilySequence
sub-class.
Any singleton instance in Java is only a singleton per class loader if created based on and utilising intrinsic class features.
Though the standard ArraySequence
hashCode
and
equals(Object)
works for singleton sub-classes of it,
faster versions of the two are implemented here to take advantage of
the singleton behaviour.
DanishAlphabetSequence
,
NorwegianAlphabetSequence
,
SimpsonsAndBouvierFamilySequence
,
SmileySequence
,
MutatedSimpsonsFamilySequence
Nested Class Summary | |
---|---|
private static class |
SimpsonsFamilySequence.Instance
An instance container class that when loaded will create the SimpsonsFamilySequence instance to use and return
from the getFamily() method. |
Nested classes/interfaces inherited from interface dk.rode.thesis.meta.model.Sequence |
---|
Sequence.State |
Field Summary | |
---|---|
(package private) static String[] |
members
The primary members in The Simpsons family. |
static int |
SIZE
The number of primary members in The Simpsons family. |
Fields inherited from class dk.rode.thesis.meta.model.ArraySequence |
---|
elements, index |
Fields inherited from class dk.rode.thesis.meta.model.AbstractSequence |
---|
state |
Constructor Summary | |
---|---|
private |
SimpsonsFamilySequence()
Private no-arg constructor for singleton creation. |
protected |
SimpsonsFamilySequence(SimpsonsFamilySequence sequence)
Sub-class copy constructor constructor. |
protected |
SimpsonsFamilySequence(String... members)
Sub-class constructor. |
Method Summary | |
---|---|
SimpsonsFamilySequence |
copy()
Returns this instance. |
boolean |
equals(Object object)
Returns true if object is an array sequence having the
same type as this array sequence, using an equivalent
array, and is at the same sequence index, false if not. |
static SimpsonsFamilySequence |
getFamily()
Returns the SimpsonsFamilySequence singleton
instance to use. |
int |
hashCode()
Returns the hash code of this sequence. |
Methods inherited from class dk.rode.thesis.meta.model.ArraySequence |
---|
bounded, consistent, current, next, reset, size, unique |
Methods inherited from class dk.rode.thesis.meta.model.AbstractSequence |
---|
getStringablePolicy, state, toString, toString |
Methods inherited from class java.lang.Object |
---|
clone, finalize, getClass, 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 |
---|
static final String[] members
public static final int SIZE
Implementation notes:
Accessing this static field will before getFamily()
will not cause the singleton instance to be created!
DanishAlphabetSequence.SIZE
,
NorwegianAlphabetSequence.SIZE
,
SimpsonsAndBouvierFamilySequence.SIZE
,
SmileySequence.SIZE
Constructor Detail |
---|
private SimpsonsFamilySequence()
SingletonError
- If another class tries to invoke
this constructor (via reflection).protected SimpsonsFamilySequence(SimpsonsFamilySequence sequence)
Only a sub-class of this sequence can invoke this constructor!
Any other context invoking it will cause a
SingletonError
to be thrown.
sequence
- The sequence to copy; cannot be null.
NullPointerException
- If sequence
is null.
SingletonError
- If a non sub-class context
tries to invoke this constructor.protected SimpsonsFamilySequence(String... members)
Only a sub-class of this sequence can invoke this constructor!
Any other context invoking it will cause a
SingletonError
to be thrown.
members
- The family members of the family; cannot be null,
or empty.
NullPointerException
- If members
is null.
IllegalArgumentException
- If members
is empty.
SingletonError
- If a non sub-class context
tries to invoke this constructor.Method Detail |
---|
public SimpsonsFamilySequence copy()
public boolean equals(Object object)
ArraySequence
object
is an array sequence having the
same type as this array sequence, using an equivalent
array, and is at the same sequence index, false if not.
equals
in class ArraySequence<String>
object
- The object to test; can be null.
public static SimpsonsFamilySequence getFamily()
SimpsonsFamilySequence
singleton
instance to use. The singleton instance is not created before the first time this method is invoked!
Implementation notes:
Because this method is static it cannot be overridden. However,
it cannot be declared final because we support singleton inheritance:
a class does not allow two static methods with the same signature.
So, if declared final, sub-classes could not define their own
getFamily
method to hide this method to return the
proper instance.
Singleton
public int hashCode()
ArraySequence
hashCode
in class ArraySequence<String>
|
Gunni Rode / rode.dk | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |