So we know that ActionScript 3.0 at present doesn’t allow for private constructors in order to conform to ECMA standards, which in turn means that when we write our Singletons we aren’t really getting the real deal.
Tink and I experimented with a little idea last night that might help with this. Very simple code as follows:
package ...
{
class SomeSingleton
{
private static var instance:SomeBusinessDelegate;
private static var instantiatingSingleton:Boolean = false;
public SomeSingleton()
{
if( !instantiatingSingleton )
{
throw new Error( "SomeSingletonis a Singleton and must be accessed through the getInstance() static method" );
}
}
public static function getInstance() : SomeSingleton
{
if( !instance)
{
instantiatingSingleton = true;
instance = new SomeSingleton();
instantiatingSingleton = false;
}
return instance;
}
}
}
So this gives us one extra layer of security when it comes to someone accidentally instantiating an instance of our Singleton. On a different note, I’d like to see “throws” added to ECMA too so that the programmer is forced to catch these errors or at least expects them without digging through the code (if at all available).
Note that this uses an old trick that also applies to emulating Abstract classes, but below you can see that if your Singleton is also abstract (in this case our SomeBusinessDelegate) you have to change things a little bit:
package ...
{
class SomeBusinessDelegate extends AbstractDelegate
{
private static var instance:SomeBusinessDelegate;
public SomeBusinessDelegate()
{
if( !instantiatingSingleton )
{
throw new Error( "SomeBusinessDelegate is a Singleton and must be accessed through the getInstance() static method" );
}
}
public static function getInstance() : BusinessDelegate
{
if( !instance )
{
instantiatingSingleton = true;
instance = new BusinessDelegate();
instantiatingSingleton = false;
}
return instance;
}
}
}
package ...
{
class AbstractDelegate extends EventDispatcher
{
private static var instance:AbstractDelegate ;
private static var instantiatingSingleton:Boolean = false;
public AbstractDelegate ()
{
if( !instantiatingSingleton )
{
throw new Error( "SomeBusinessDelegate is a Singleton and must be accessed through the getInstance() static method" );
}
}
}
}
Obviously we have no getInstance() static method in our Abstract class.