|
Evaluating Software Design Patterns — the "Gang of Four" patterns implemented in Java 6 |
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: REQUIRED | OPTIONAL | DETAIL: ELEMENT |
@Documented @Retention(value=RUNTIME) @Target(value=TYPE) public @interface Singleton
A singleton annotation identifies a given type
already at compile-time as a singleton by identifying the
static method returning an instance of the
annotated type. The method can either accept no arguments,
or a fixed number of java.lang.String
arguments.
The method is known as the singleton method. By default,
a method name of getInstance
is assumed, corresponding
to the static method Foo getInstance()
in the Foo
class.
Any type declared as a Singleton
can be utilised
in a stateless singleton registry
.
Implementation notes:
An annotation is preferred over an interface, because different
singleton objects offer no common functionality except for conceptual
behaviour in form of only a single instance available. The singleton
method must in any case be static, and interfaces cannot declare
static methods. An annotation also allows for different method
names for different types.
Furthermore, neither an annotation or an interface can guarantee that the implementing class does not disclose an accessible constructor. However, by using annotations, Sun's Annotation Processing Tool (APT) could be primed with a handler to enforce that all found annotated types do not expose accessible constructors, and check the existence of the specified singleton method, already at compile time.
A consequence of not using an interface is that singleton registries
cannot impose direct bounds on the type parameters used, for example
<T extends Singleton>
for a given Singleton
interface. However, the SingletonRegistry
still allows for
such parameterisation by specifying an appropriate type parameter.
A general parameterised singleton method - corresponding to a parameterised
Factory Method - is not
practically feasible using this annotation without involving a lot
of String
parsing; that is, using an argument to determine the
actual singleton instance to fetch of any type. Hence, we only allow
no arguments or a fixed number of String
arguments here. However, the
idea to use reflection to access the singleton method could easily be extended
to allow for more complex protocols as Java's reflection mechanism can mimic all
normal method (and constructor) invocation scenarios. It could also be extended
so any type could be a singleton type, but that would require a registry
keeping taps on created instances and would only work if all
access to acquire/create instances were via the registry. A scenario were this
could work could be an Abstract Factory
that internally uses such a registry.
The annotation is not inherited, because there is no way a given class can tell if a sub-class will be implemented as a singleton as well. Even so, the sub-class could decide to use a different singleton method.
An alternative to letting the annotation specify the method name could
be to use an annotation as a marker on the method to use. A
visitor of some sorts would then be required to traverse the methods
declared in a given type to find the (first) one with the marker
annotation that fits the profile of a static method returning a proper
singleton type. This roughly corresponds to the idea behind the
Executor
annotation, which is used in the
Observer pattern (see the
ObserverManager
class). Here, however, annotation of the
singleton type itself is the logical design choice.
Optional Element Summary | |
---|---|
String[] |
arguments
Returns the fixed java.lang.String arguments to supply each time the
singleton method identified by value() is invoked, if any. |
String |
value
The name of the singleton method to access the singleton instance. |
public abstract String[] arguments
java.lang.String
arguments to supply each time the
singleton method identified by value()
is invoked, if any.
The singleton method used must formally declare the same number of
parameters of type java.lang.String
.
public abstract String value
The method name must represent a static method returning an instance
of the annotated type. The name must not include parentheses.
The method can either be a no-argument method, or a method accepting
a fixed number of java.lang.String
arguments.
Argument values are fixed and specified by arguments()
.
getInstance
(accepting no arguments).
|
Gunni Rode / rode.dk | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: REQUIRED | OPTIONAL | DETAIL: ELEMENT |