|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object mandala.util.SingletonGiver
This class provides a general purpose singleton implementation.
Each instance of this class is associated with:
SingletonGiver.Factory
implementation - which allows the creation of singleton;Map
implementation which
prevent multiple instanciation of a singleton for the same
object.The method getInstance(Object, Object[] args)
returns the
singleton mapped to the specified object
in the
cache or the one returned by the factory. In this latter
case, the singleton is also mapped to the specified
object
in the cache using the register(Object
singleton, Object object)
method.
Users must be aware of the mapping they want for their
singletons. Default mapping is done by a IdentityHashMap
which provides the "natural behavior": two objects share the same
singleton if and only if they are the same objects (in the sense of
the '==' operator). Note that it is possible to use a "traditionnal" Map
implementation such as HashMap
for the
mapping. In this case, two objects share the same singleton if and
only if they are equals (in the sense of Object.equals(Object)
).
The method unregister(Object)
allows mapping to be removed from
the cache. This implementation uses a WeakValuesMap
wrapper so
registered objects don't have to use theirObject.finalize()
method
to ensure they are unregistered when garbage collected. This means,
singletons may be garbage collected when they are not strongly
referenced. Hence, multiple call to getInstance(Object)
may
occurs for the same object when a singleton has already been mapped
in the cache but has been garbage collected. Singleton
implementation must define a readResolve()
method in order to
behave as singleton on deserialization. The general schema for a
singleton implementation is given by the following code:
public class MyClass { private key; // The key for which this instance stand for a singleton. // Do not provide a public constructor protected MyClass(Object key, Param1 param1, ..., ParamN paramN) { this.key = key; ... } private static final SingletonGiver singletonGiver = new SingletonGiver(new SingletonGiver.Factory() { // Implements my singleton policy public Object newInstance(Object key, Object[] args) { // if args.length == 1 it means singleton is used in // deserialization (see readResolve() below) and that // args[0] contains the reference to return. if (args.length == 1) { return args[0]; } if (args.length == N) { return new MyClass(object, param1, ..., paramN); } throw new Error("Wrong number of arguments!"); } }); // Singleton instance are given by the following method public static MyClass getInstance(Object key, Param1 param1, ..., ParamN paramN) { return (MyClass) singletonGiver.getInstance(key, new Object[]{param1, ... paramN}); } // Warning : Singleton must be respected! readResolve() help us in this way! private Object readResolve() throws ObjectStreamException { // Do not create a MyClass instance with 'new' as in getInstance(), use // 'this' instead return singletonGiver.getInstance(key, new Object[]{this}); }
Nested Class Summary | |
static interface |
SingletonGiver.Factory
Interface that define how singleton are created. |
Field Summary | |
protected java.util.Map |
cache
References cache. |
protected SingletonGiver.Factory |
factory
The factory used to create singletons. |
protected static Syslog |
syslog
Message logger. |
Constructor Summary | |
SingletonGiver(SingletonGiver.Factory factory)
Creates a new SingletonGiver instance. |
|
SingletonGiver(SingletonGiver.Factory factory,
java.util.Map cache)
Creates a new SingletonGiver instance. |
Method Summary | |
java.lang.Object |
getInstance(java.lang.Object object)
Equivalent to getInstance(object, null) . |
java.lang.Object |
getInstance(java.lang.Object object,
java.lang.Object[] args)
Returns the singleton to which the specified object is mapped to. |
static Syslog |
getSyslog()
Returns the logger. |
void |
register(java.lang.Object object,
java.lang.Object singleton)
Register a mapping. |
static void |
setSyslog(Syslog syslog)
Sets the logger. |
void |
unregister(java.lang.Object object)
Unregister a mapping. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
protected static Syslog syslog
Message logger.
Each message (debug, log, warning, error, ...) are wrote to this message logger.
Syslog
protected final SingletonGiver.Factory factory
The factory used to create singletons.
protected final java.util.Map cache
References cache.
Constructor Detail |
public SingletonGiver(SingletonGiver.Factory factory)
Creates a new SingletonGiver
instance.
Use the default IdentityHashMap
implementation for the
cache.
factory
- the factory used to create new singletonSingletonGiver.Factory
public SingletonGiver(SingletonGiver.Factory factory, java.util.Map cache)
Creates a new SingletonGiver
instance.
factory
- the factory used to create new singletoncache
- the map implementation to use as a cache
Method Detail |
public static Syslog getSyslog()
Returns the logger.
public static void setSyslog(Syslog syslog)
Sets the logger.
syslog
- the logger to setpublic void register(java.lang.Object object, java.lang.Object singleton)
Register a mapping.
object
- the object mapped to the given singletonsingleton
- the singletonpublic void unregister(java.lang.Object object)
Unregister a mapping.
object
- the object previously mapped to a singletonpublic java.lang.Object getInstance(java.lang.Object object)
Equivalent to getInstance(object, null)
.
getInstance(Object, Object[])
public java.lang.Object getInstance(java.lang.Object object, java.lang.Object[] args)
Returns the singleton to which the specified object is mapped to.
If a mapping has already been registered for the given object, the
mapped singleton is returned, otherwise a new one is created
using the current factory SingletonGiver.Factory.newInstance(Object, Object[])
,
and returned after having registered its mapping.
Notice that the mapping depends on the cache
implementation: if the mapping is based on the '==' operator (such as
the IdentityHashMap
class), then:
getInstance(a) == getInstance(b) <=> a == bOtherwise, if the mapping is based on the
Object.equals(Object)
,
(as documented by the Map
interface and as implemented
by HashMap
), then:getInstance(a) == getInstance(b) <=> a.equals(b)
object
- the object to get a singleton fromargs
- the arguments to use to create the mapped singleton
for the sepcified object
SingletonGiver.Factory
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |