followup: learning the singleton pattern

February 23rd, 2009 Leave a reply »

Just over a year ago, I wrote about learning the singleton design pattern (and then implementing it in ActionScript). I was happy to have found I could use singletons in AS3, since I had several use cases in mind.

Since then, I’ve learned more about things like dependency injection and the Law of Demeter. I’ve learned more about test-driven development. And I’ve learned something else: Global state is almost universally a complicator when combined with these practices. The other thing I’ve learned: the singleton pattern IS global state.

Let’s walk through this. Suppose you are developing an application which is using an in-memory storage implementation (hey, it’s a young app). You write the storage using the singleton pattern – in any class that may need a reference to that, you just do

StorageImpl.getInstance().addPreferenceItem(new Preference("whatever"));

This works, and appears to work well.

Now, a month or two later, you have a requirement for database persistance in the app. You write another implementation, call it DatabaseStorageImpl. You change all of your code over to this:

DatabaseStorageImpl.getInstance().addPreferenceItem(new Preference("whatever"));

And everything still works. Except for the one or two places you missed when converting it over. Except for your unit tests, which now either don’t work, or require the presence of your database.

How do your tests know which implementation is being used in the code they test?

The solution to all of the above problems is dependency injection. I’m not going to go deeply into this now, but here is a great explanation of the pros and cons: Misko Hevery’s “Global State and Singletons” (Clean Code Talks)

Anyway, here’s the upshot: I’ll leave up my AS3 singleton implementation, but use it at your own risk. My policy at this point is to avoid singletons unless I have a very specific reason NOT to use dependency injection – and I have yet to come up with such a reason.

Leave a Reply