AS3 Singletons, revisited

The topic of Singletons in ActionScript 3.0 has been coming up again lately and it has been very interesting to see all of the unique solutions the community has come up with. In particular I like the idea of having Singleton metadata which would allow the compiler do all of the work for us.

Personally I feel the Singleton pattern is extremely useful. It is arguably one of the most common design patterns around today. Practically every management centric API requires a Singleton one way or another. Some developers claim that the Singleton pattern is nothing more than a euphemism for a global variable, to some extent this is true, however the intent of a Singleton is clearly different.

As useful as the Singleton pattern is my biggest complaint about Singletons has always been the actual construction code required to create / protect the Singleton instance. This extra code often becomes quite verbose and it is annoying to have to sift through all of the Singleton code when working with the actual class implementation code. It would also be nice to not have to constantly re-write the Singleton construction and implementation code every time a Singleton is needed.

So is there a way around all of this? Yes!

I developed a simple class called SingletonMonitor which singleton classes can extend to allow the omission of all Singleton specific construction code. All that is needed is to have the class which is to be a Singleton extend SingletonMonitor. That’s it. No more getInstance(), inner classes, type checking and so on is needed. As a best practice I recommend that you define the Singleton instance in the class itself in order to improve code readability.

An example demonstrating how to use the SingletonMonitor can be seen in the following:

As you can see no Singleton construction code is needed. Additionally, by extending SingletonMonitor you are clearly stating that the class is intended to be a Singleton.

So how is this accomplished? It’s pretty simple…

When a derived class is instantiated the SingletonMonitor constructor is invoked, the constructor parses the current stack trace in order to determine the derived class’ name (hence the hack). The name of the derived class is then used as a key in the SingletonMonitor hash table. When a subsequent instantiation of the class is made SingletonMonitor checks the name of the class and if it has previously been defined in the hash an exception is thrown. I originally developed this using introspection to determine the fully qualified name of the class, however the preferred implementation is to have the class eagerly instantiated at compiled time (i.e. constant), thus the stack trace is not available.

Admittedly this is a bit of a hack, but so are the alternatives, otherwise this issue would never have been a topic of discussion in the first place.

However what I like about this new approach is that the Singleton is being managed outside of it’s concrete implementation, and that is the goal of this post; to present an alternative means of managing Singleton construction. Through this the Singleton construction and management code can be omitted as it is being handled by a completely separate object.

So the SingletonMonitor was the first example of how Singleton management can be achieved. The second example demonstrates the Singleton management approach implemented via composition as opposed to inheritance – which is my preferred mechanism of Singleton Management. In addition to creating the SingletonMonitor which utilizes inheritance I also created a SingletonManager which utilizes composition. The SingletonManager is the implementation I recommend and prefer.

An example demonstrating how to use the SingletonManager can be seen in the following:

The SingletonManager requires the class constructor to invoke SingletonManager.validateInstance and pass in a reference of the instance. This is automated in the SingletonMonitor as the class name is determined automatically which is convenient, however the readability of the SingletonManager is preferred as it clearly states intent. Additionally the SingletonManager guarantees the correct type is resolved.

So this is a new way of thinking about Singletons; to provide a management system from which Singleton construction and protection can consistently provided.

To be honest, this was really just an experiment I have been playing around with for some time now that I thought I should share, I am not sure if I would use the SingletonMonitor in production code as the parsing of the stack trace just feels a bit to much like a hack. However I will most likely utilize the SingeltonManager moving forward as it is a great way to abstract Singleton construction and protection from the class implementation.

My hope is that there will be a true solution available as we move forward, but for the time being if you would like to create Singletons without the need for all of the Singleton implementation code feel free to extend SingletonMonitor for management or SingletonManager for compositional management.

{ 7 comments to read ... please submit one more! }

  1. Looks like this has been “Resolved” in the ECMA spec, . Maybe we’ll see this spec addition in the future?

  2. Hey Sam,

    It would be great if there was a proper means we could use to create Singletons. I am interested in this addition, however I get a 404 when I try to hit the URL you sent.

    Thanks,
    Eric

  3. Great use of the stack trace! The only setback I see to other implementations is that there’s no lazy instantiation, but all Singleton instances are created during initialization. But I guess one could use the same stack trace mechanism to implement a getInstance-method in the SingletonMonitor itself.

  4. Hey artman,

    Conceptually, the SingletonMonitor is intended to provide an alternative means for classes to be Singletons without the need to implement Singleton specific construction code, yet still provide a mechanism which would enforce there is only ever one instance of the class. This is achieved through inheritance.

    The parsing of the stack trace is simply used as a convenience so that derived classes are not required to inform the superclass of their existence. By parsing the call stack the derived class can easily be located.

    The static const which defines the the Singleton instance is intended so that the traditional getInstance() implementation can be omitted.

    With that being said, one could just as easily implement a getInstance() and the SingletonMonitor would behave the same way. Eager instantiation is an option, not a requirement.

    Additionally, by lazily instantiating the class (i.e. Instantiating the class at runtime) you can use introspection (e.g. getClassName) to determine the fully qualified name of the class, which will protect the class from potential naming collisions.

    – Eric

  5. Bjorn Schultheiss

    I like not having to include the implementation in the each singleton class.

    But using inheritance just for a singleton is kind of limiting.

  6. Hey Bjorn,

    I would have to disagree that using inheritance just for a Singleton is kind of limiting since Singleton’s typically use composition over inheritance anyway and it is also rare to have a Singleton extend another class.

    Conceptually, the SingletonMonitor is intended to rethink how Singletons are implemented, that is, rather than trying to create a bullet proof singleton implementation, we can rethink the problem altogether and prescribe an alternative solution – one which allows all Singleton construction code to be removed from the actual class implementation code.

    With that being said, if you prefer to not use inheritance you could simply use the SingletonManager class which manages singleton construction via composition. As I mentioned in the post this would require a bit more implementation work up front however it is easy to implement.

    Check out: http://code.ericfeminella.com/classes/as3/SingletonManager.as.html

    I prefer to not use inheritance as it is cleaner and makes a bit more sense. It requires a more work as the Singleton class must implement a constructor and invoke SingletonManager.valifdateInsatance. To be honest I prefer this approach as it is not a hack but rather just another way to manage the Singleton construction / management process.

    – Eric

  7. I did implent all of the above, includeing

    trace(MyClass.instance);

    in the first frame.
    In strict mode I got an error saying: 1119: Access of possibly undefined property instance through a reference with static type Class.

    in non-strict mode I got this: undefined

    What am I missing, should there be any settings done?

{ 0 Pingbacks/Trackbacks }