package com.ericfeminella.utils
{
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
import flash.errors.IllegalOperationError;
/**
*
* All static class which provides an API which enforces classes
* which are to follow the Singleton pattern are only ever have a
* single instance instantiated per application, by monitoring the
* instantiation of derived classes this requirement is ensured,
* thus elliminating the Singleton implementation code from the
* actual class implementation.
*
* <p>
* Upon instantiation of a Singleton class, the class constructor
* invokes <code>SingletonManager.validateInstance</code> and simply
* passes a reference to the instance.
* </p>
*
* @example this can be seen in the following
*
* <listing version="3.0">
*
* SingletonManager.validateInstance( this );
*
* </listing>
*
* <p>
* The fully qualified class name is then used as the unique key in
* the HashMap instance (<code>singletons</code>). The class name /
* key is then assigned a Boolean value of true. When a subsequent
* instantiation of the Singleton class occurs the Singleton class
* repeats the process of invoking SingletonManager.validateInstance
* to see if the Singleton class has been mapped previously, and if
* so an exception is thrown.
* </p>
*
* <p>
* Classes must invoke <code>SingletonManager.validateInstance</code>
* from within their constructor in order to garuntee they are only to
* have single instance created, hence the term Singleton.
* </p>
*
* @example The following example demonstrates how a class can invoke
* <code>SingletonManager.validateInstance</code> in order to simplify
* the Singleton construction process by delegating Singleton Management
* to a specific object rather than the class implementation itself
*
* <listing version="3.0">
*
* package com.examples
* {
* public class SomeSingleton
* {
* // Defines the singleton instance of SomeSingleton
* public static const instance:SomeSingleton = new SomeSingleton();
*
* // Singelton class passes in a reference of the instance,
* // SingletonManager determines the fully qualified name
* // of the class and validates the instance
* public function SomeSingleton()
* {
* SingletonManager.validateInstance( this );
* }
* }
* }
*
* </listing>
*
* <p>
* The above example guarantees that only one instance of the example class
* "SomeSingleton" can ever be instantiated.
* </p>
*
*/
public final class SingletonManager
{
/**
*
* Defines a static HashMap which contains a reference to all
* Singleton class types.
*
* <p>
* A unique key based on the Singleton class name is added to the
* map for each type which is to only contain a single instance
* </p>
*
*/
private static const singletons:Dictionary = new Dictionary();
/**
*
* Validates a new Singleton class instance to determine if the
* class has previously been instantiated, if so, an Exception
* is thrown, thus indicating that the class is a Singleton and
* is only intended to have a single instance instantiated
*
* @param Singleton class instance which has been instantiated
*
*/
public static function validateInstance(instance:*) : void
{
var className:String = getQualifiedClassName( instance );
if ( singletons[ className ] )
{
throw new IllegalOperationError( "Singleton Exception. Only one instance is allowed for type: " + className );
}
singletons[ className ] = true;
}
}
}