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

  1. Unformatt / August 16th, 2007 23:28

    This is nice – I guess ECMA doesn’t like private constructors? Any reason not to include the PrivateClass in the package?

  2. gabriel / August 17th, 2007 07:55

    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.

  3. robert shearing / August 20th, 2007 01:23

    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;
    }
    }
    }

  4. Gabriel Handford / October 2nd, 2007 03:52

    Shouldn’t it be:

    public static var get instance():Singleton { return getInstance(); }

    and change all the instance to _instance (to avoid the conflict)?

  5. Rob / August 24th, 2008 07:01

    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!”);
    }

  6. gabriel / August 25th, 2008 13:06

    would be a stupid developer to pass null.

  7. dimpiax / August 27th, 2008 13:44

    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’);
    }

  8. Cotton / November 2nd, 2008 02:06

    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());
    }

    }

    }

  9. estetik / June 3rd, 2009 22:55

    “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?”