Singletons for AS3
Posted in Programming, Tips on June 21st, 2010 by ManuelSingletons the curse and blessing of many coding projects.
Among other pitfalls, you’ll basically introduce a global variable in your system, making UnitTests much harder.
Why Singletons?
Despite the possible problems they can present, they are just so darn handy sometimes. If there is some part of your code that needs to be accessed from almost anywhere in the system (like the sound system, or a global error text console and such) there is hardly a better way to achieve that.
Alternatives?
A global messages system to communicate between objects can achieve the same effect. We used to make heavy use of such a system system. However, according to our experience, maintaining that system is fairly time consuming for it gets more and more complicated over time. Besides, if a messaging system allows queing, you’ll never really now where and why a message was sent because you loose the stacktrace. So, right know we are reducing the work-load done by the message system, handing it over to direct singletons access. By this, we increased debugability and clearity of data transfer. Besides, using singleton access is much faster than routing it through our messaging system.
How to Do It?
The web already offers a bunch of solutions (1). Most of them boil down to implement the singleton code over and over again in each singleton. We didn’t like that and tried to come up with a better solution. When we define a singleton it looks like that:
/**
* Accesing this class somewhere in the code looks like this:
* cSomeController.GetInstance().DoSomething();
*/
public class cSomeController extends cSingleton
{
public static function GetInstance():cSomeController
{
return cSingleton.GetInstance(cSomeController);
}
public function DoSomething()
{
trace("Yes, I can.")
}
}
That is much simpler than copying&pasting the complete singleton code over and over. The corresponsing cSingleton-class looks like that:
package rsengine.patterns
{
import flash.utils.Dictionary;
/** * Singleton base class */ public class cSingleton { private static var m_instances:Dictionary = new Dictionary(); private static var m_unlockConstructor:Boolean = false; public function cSingleton() { if (m_unlockConstructor == false) throw Error("You cannot create an instance of a singleton." + "Use GetInstance instead!"); } /** * Returns an instance of the specified class * @param _class class * @return instance of specified class */ public static function GetInstance(_class:Class) : * { if (m_instances[_class] == null) { m_unlockConstructor = true; m_instances[_class] = new _class(); m_unlockConstructor = false; } return m_instances[_class] ; } } }
Our singleton implementation significantly reduced the amount of code you have to copy&paste compared to the other singleton implementations out there on the net. We do know that our implementation of GetInstance() is a little slower (because of the Dictionary look up). Since you shouldn’t have too many calls to the GetInstance method this is probably nothing to worry about too much. Nevertheless, you could cache the result of GetInstance() if you do need to access the singleton more than once (e.g. in a loop).
Have fun and happy coding
Manuel
AS3: Singletons, ActionScript 3 Singleton Redux, google
Popularity: 19% [?]

