views:

135

answers:

5

I know actionscript does not allowed private contstructor at any time and But if i want to write a sinlgleton class in action script So how to implement it in actionscript.

Can anyone provide an sample example of a singleton pattern in actionscript?

+1  A: 
public class Singleton {
    private static var _instance:Singleton;

    public **static** function get instance():Singleton
    {
        if (_instance == null)
        {
             _instance = new Singleton();
        }
        return _instance;
    }

    public function Singleton()

    {
        if (_instance != null) throw new Error("You can't create Singleton twice!");
    }
}

Runtime check in lack of private constructor.

alxx
+4  A: 

You need to alter Alxx's answer slightly as it doesn't stop new Singleton() from working...

public class Singleton {
    private static var _instance : Singleton;

    public function Singleton( newBlocker : ClassLock ) {
    }

    public static function getInstance() : Singleton {
        if ( _instance == null ) {
            _instance = new Singleton( new ClassLock() );
        }
        return _instance;
    }
}
class ClassLock{}

The private class is used by the Singleton to stop other classes simply doing new Singleton() initially and then getting a second instance by doing getInstance().

Note that this still isn't watertight... If someone is determined to break it, they can get access to the private class, but this is about the best option for Singletons.

Gregor Kiddie
+2  A: 

I use something like this:

package singletons
{

    [Bindable]
    public class MySingleton
    {
        private static var _instance:MySingleton;

        public function MySingleton(e:Enforcer)  {
            if(e == null) {
                throw new Error("Hey!  You can't do that!  Call getInstance() instead!");
            }   
        }

        public static function getInstance():MySingleton {
            if(_instance == null) {
                _instance = new MySingleton (new Enforcer);
            }
            return _instance;
        }
    }
}

// an empty, private class, used to prevent outside sources from instantiating this locator
// directly, without using the getInstance() function....
class Enforcer{}
reidLinden
+1  A: 

basically, all answers are right, those of reid and gregor provide more compile time safety. I suppose, the best thing is however, to declare an interface for the singleton and a private implementor exposed through a static class:

package {
    interface IFoo {
        function foo():void;
    }
}

and then:

package Foo {
    private static var _instance:IFoo;
    public static function getInstance():IFoo {
        if (_instance == null) _instance = new Impl();
        return _instance;
    }
}
class Impl implements IFoo {
    public function foo():void {
        trace("fooooooooooooooooooo");
    }
}

this doesn't rely on runtime errors for safety. Also, it lowers coupling.

greetz
back2dos

back2dos
A: 

I use this approach ...

package
{
    public class Main
    {
        private static var _instance:Main;
        private static var _singletonLock:Boolean = false;

        /**
         * Creates a new instance of the class.
         */
        public function Main()
        {
            if (!_singletonLock) throw new SingletonException(this);
        }

        /**
         * Returns the singleton instance of the class.
         */
        public static function get instance():Main
        {
            if (_instance == null)
            {
                _singletonLock = true;
                _instance = new Main();
                _singletonLock = false;
            }
            return _instance;
        }
    }
}

... not as terse as some other methods but it's absolutely safe and there's no need for an empty package-level class. Also note the shortcut with SingletonException which is a class that extends the AS3 Error class and saves typing some code when using more than one Singleton ...

package
{
    public class SingletonException extends Error
    {
        public function SingletonException(object:Object)
        {
            super("Tried to instantiate the singleton " + object + " through it's constructor."
                + " Use the 'instance' property to get an instance of this singleton.");
        }
    }
}
loungelizard