November 2007 Archives

ActionScript 3 Singleton Redux

| 14 Comments | No TrackBacks

Not to beat a dead horse, but....

Ever since developers have been using ActionScript 3 the quest for the perfect Singleton has been underway. The heart of the issue is that there are no private constructors in ActionScript 3. Thus, it's been a tricky road trying to find the best way to prevent other developers from inadvertently invoking a Singleton's constructor and creating an additional (and erroneous) instance.

For example, a quick google search yields quite a few results. Here are a handful of them that I've tried to place in chronological order:

What do I think? My initial reaction was to not worry about it. Seriously, what does it matter? Do we really need compile time checking? Isn't runtime checking and unit testing enough? If a developer uses the class wrong, is that the class author's fault? As long as there is documentation as to what the class is and how it's used, then this is really a non-issue at best and trivial at worst.

Admittedly that's a bit of a naive attitude. However, in over a year of not caring about the private constructor issue I can honestly say that I've never run into a problem with singletons, or had any of my team members accidentally use them the wrong way.

It was actually a combination of other factors (and personal preference) that made me revisit the singleton pattern. The singleton technique that I prefer was developed to address the other issues I was running into and to reflect my personal coding style. While I was at it, I figured I might as well address the private constructor issue too. After all, we all love being smacked around by the compiler sometimes.

The technique I prefer has the following highlights:

  • Usage of static instance read-only property instead of a static getInstance() function. This is somewhat a matter of style and personal preference, but I prefer the succinctness of the read-only property. This is especially obvious when the singleton is used in binding expressions. Plus, getInstance() is so 1990s Java which ActionScript is most definitely not. I kid, I kid. But seriously, ".instance" is cooler.
  • Usage of a private lock class to prevent outside construction. While this is a common theme in the above links, my approach is slightly different. Instead of passing an instance of the private locking class to the constructor, I just pass the Class reference itself. This does two things. First, it clarifies the conditional check in the constructor. The test for the proper locking Class reference communicates the code's intent better than the traditional check for not null. Second, it encapsulates the private locking class itself. The constructor's argument is simply lock:Class which doesn't expose the name of the private locking class to the outside world, but still communicates that the constructor is locked.
  • Removal of 'Unable to bind' warnings in Flex 2. When you use a singleton in a binding expression, it's typical to have the Console log flooded with warning messages indicating that binding to the instance property will not be able to detect updates. My singleton version fixes these warnings.
  • Use of const instead of var for the instance storage. This one is pretty obvious, but using const here communicates intent better. The variable storing the singleton instance is not allowed to change so const is the better choice.

So, with that said, I thought it was worth throwing my singleton version into the ring. This is the method I prefer. If you like it, great. If not, that's fine too. No hard feelings. Really.

Sample code is after the jump.

Flex.org - The Directory for Flex

Archives