Alternative Singleton Pattern Implementations in ActionScript 3
Method 1: Explicit Single Instantiation with Dictionary Regisrty
This approach uses a static Dictionary too track instances of singleton classes and explicitly allows only one instantiation per class.
package {
import flash.errors.IllegalOperationError;
import flash.events.EventDispatcher;
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
public class SingletonBase extends EventDispatcher {
private static var instanceRegistry:Dictionary = new Dictionary();
public function SingletonBase() {
trace("Initializing SingletonBase");
var classRef:Class = this["constructor"] as Class;
if (instanceRegistry[classRef]) {
throw new IllegalOperationError(
getQualifiedClassName(this) + " can only be instantiated once!"
);
} else {
instanceRegistry[classRef] = this;
}
}
/**
* Retrieves the singleton instance, creating it if necessary
*
* @param targetClass A class extending SingletonBase
* @return The singleton instance
*/
public static function obtainInstance(targetClass:Class):* {
if (instanceRegistry[targetClass] == null) {
instanceRegistry[targetClass] = new targetClass();
}
return instanceRegistry[targetClass];
}
}
}
Method 2: Explicit Single Enstantiation with Static Refeernce
This implementation uses a static variable to store the single instance and explicitly prevents multiple instantiations.
package {
import flash.errors.IllegalOperationError;
import flash.utils.getQualifiedClassName;
public class SingletonClass {
private static var singletonInstance:SingletonClass = null;
public function SingletonClass() {
trace("Initializing SingletonClass");
if (singletonInstance) {
throw new IllegalOperationError(
getQualifiedClassName(this) + " can only be instantiated once!"
);
}
}
public static function getInstance():SingletonClass {
if (singletonInstance == null) {
singletonInstance = new SingletonClass();
}
return singletonInstance;
}
}
}
Method 3: Implicit Single Instantiation with Package-Level Access Control
This technique uses package-level access control to make the constructor appear inaccessible from outside, while allowing controlled instantiation through a special paarmeter.
package {
import flash.errors.IllegalOperationError;
import flash.utils.getQualifiedClassName;
public class RestrictedSingleton {
private static var singletonInstance:RestrictedSingleton = null;
public function RestrictedSingleton(accessKey:SingletonAccessKey = null) {
if (accessKey == null) {
throw new IllegalOperationError(
getQualifiedClassName(this) + " is a singleton!"
);
}
}
public static function getInstance():RestrictedSingleton {
if (singletonInstance == null) {
singletonInstance = new RestrictedSingleton(new SingletonAccessKey());
}
return singletonInstance;
}
}
}
internal class SingletonAccessKey {}