AS3.0 Better Singletons
I’ve found a better more robust way of enforcing singletons in AS3.0
[as]
package
{
public class Singleton
{
public static var instance:Singleton;
public static function getInstance():Singleton
{
if( instance == null ) instance = new Singleton( new SingletonEnforcer() );
return instance;
}
public function Singleton( pvt:SingletonEnforcer )
{
// init class
}
}
}
internal class SingletonEnforcer{}
[/as]
Note: The class “SingletonEnforcer” is actually placed within the same .as file as the Singleton class, but placed outside the package{} parenthesis, therefore, the class “SingletonEnforcer” can only be accessed from within this .as file, so if the Singleton’s constructor is called from anywhere else, you’ll get an error.
9 Comments so far
This is nice – I guess ECMA doesn’t like private constructors? Any reason not to include the PrivateClass in the package?
Exactly, ECMA doesn’t allow private constructors. The PrivateClass is outside the package so that i can only be accessed by code within the current .as file (if it was in the package{} I’d assume it would be accessible elsewhere within the package.
I discovered another implenentation by Daniel Hai on http://www.onflex.org/code/
The private static instance variable is instantiated on declaration. Simple and clean:
package
{
public class Singleton
{
private static var instance:Singleton = new Singleton();
public function Singleton()
{
if( instance ) throw new Error( “Singleton and can only be accessed through Singleton.getInstance()” );
}
public static function getInstance():Singleton
{
return instance;
}
}
}
Shouldn’t it be:
public static var get instance():Singleton { return getInstance(); }
and change all the instance to _instance (to avoid the conflict)?
The only problem with this solution is that a developer can simply pass null into the constructor:
var s : Singleton = new Singleton(null);
You have to explicitly check the nullity and type of the parameter:
public function Singleton(enforcer:*=null){
if(enforcer==null || !(enforcer is SingletonEnforcer))
throw new Error(“FAIL!”);
}
would be a stupid developer to pass null.
This if pretty realisation of Singelton fo Me:
private static var __called : Boolean;
private static var __instance : Class;
public static function get instance() : Class {
Class.__called = true;
if(Class.__instance == null) Class.__instance = new Class();
return Class.__instance;
}
public function Class() {
if(__instance) throw Error(‘This class uses Singelton pattern.’);
else if(!__called) throw Error(‘You must access to class by Class.instance’);
}
We should keep the parameter list of construct clear.
package
{
public class Singleton
{
private static var instance:Singleton;
private static var isLock:Boolean = true;
public function Singleton ()
{
if (isLock) throw new Error(‘ooops’) else isLock = true;
}
public static function getInstance ():Singleton
{
return instance ||= (isLock = false, new Singleton());
}
}
}
“Can I map “this” information?” Or
they ask, “Is there an application I can use on our network that I can
plot this info on?”