«

»

Singletons for AS3

Singletons 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:


<pre><span style="color: #008000;">/**
* Accesing this class somewhere in the code looks like this:
* cSomeController.GetInstance().DoSomething();
*/</span>

<strong>public </strong>class cSomeController extends cSingleton
{
    <strong>public </strong><strong>static </strong>function GetInstance():cSomeController
    {
        return cSingleton.GetInstance(cSomeController);
    }

    <strong>public </strong>function DoSomething()
    {
        trace("Yes, I can.")
    }
}</pre>

That is much simpler than copying&pasting the complete singleton code over and over. The corresponsing cSingleton-class looks like that:


<pre><strong>package </strong>rsengine.patterns
{
    <strong>import </strong>flash.utils.Dictionary;</pre>
<pre><span style="color: #008000;">    /**
    * Singleton base class
    */
</span>
    <strong>public </strong>class cSingleton
    {
        <strong>private </strong><strong>static </strong>var m_instances:Dictionary = new Dictionary();
        <strong>private </strong><strong>static </strong>var m_unlockConstructor:Boolean = false;            

        <strong>public </strong>function cSingleton()
        {
          if (m_unlockConstructor == false)

          throw Error("You cannot create an instance of a singleton."
          + "Use GetInstance instead!");
        }

<span style="color: #008000;">    /**
    * Returns an instance of the specified class
    * @param _class class
    * @return instance of specified class
    */
</span>
    <strong>public </strong><strong>static </strong>function GetInstance(_class:Class) : *
    {
      if (m_instances[_class] == null)
      {
        m_unlockConstructor = true;
        m_instances[_class] = new _class();
        m_unlockConstructor = false;
      }
      return m_instances[_class] ;
    }
  }
}</pre>

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: 21% [?]

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">