Refactoring Mockingbird: Singletons

I’m starting the process of refactoring the core and components of Mockingbird. Now that we’ve settled on a featureset and UI, it’s time to go back and clean up all those unused abstractions, unnecessary architecture and *hacks* that litter the code (the byproduct of a single engineer writing all of it!).

First up: singletons (or any global state). I’m a big OOP fan. I’m a big pattern fan. I’m a big GOF fan. I don’t like singletons. Or rather, I don’t like programmers pretending that singletons are “good OOP” and that they’re somehow different than old fashioned globals. I’ve always reminded other developers, “if you’re using singletons as globals, that’s fine, it’s the proper way to do it in an OOP language. But don’t kid yourself! It’s a global with different syntax! It’s got all of the same problems!”

Singleton I love you, but you’re bringing me down | // Coding Without Comments.

This article really sums up everything much better than I could and is what inspired me to write this post. Mockingbird’s singletons have nagged me for a long time, and I resisted having them for a long time before then. I was basically using Dependency Injection, which worked, but felt like more typing and repetition than necessary for the *potential* of configurability down the road. I eventually caved and refactored those parts of the architecture around singletons. It simplified the code quite a bit (in the short term), and made prototyping much faster as I now had a nice global dumping ground for quick hacks.

But, it’s definitely given the code an awful smell. And it’s made it very brittle. Up until I saw the above post, my plan was to just convert everything back to Dependency Injection and just live with the extra boilerplate. But, there’s a better route! Factories!

So, in the above post there’s a link to the blog of the testing expert over at Google. His suggestion is to never mix object construction with logic. Simple, yes? Instead of manually handling dependency injection in each place where you need to construct an object (which has a cascading effect wherein you need more and more dependency injection!) you consolidate all of that boilerplate code to a factory. A clear example of separation of concerns.

Now, I used to be in love with factories. When I developed in C/C++ I used factories all of the time because it allowed me to consolidate memory management into the factory and strip all the mallocs out of my logic. But I cast that lesson aside when I moved to managed languages. But factories still solve the same fundamental issue of allocation as a *part* of configuration (which is what factories generically do). Obvious, yes, but I’d never seen it put quite like this.

Needless to say, it’s clicked for me. I’m now going to be introducing factories in lots of places inside of Mockingbird. Creating elements of our Game Object Model? Factory! Creating runtime instances? Factory!

To be honest, I was actually employing a bit of the factory pattern in most of the instances already. The problem was that I was not being formal enough about it, or rather I wasn’t *completely and cleanly* separating my concerns.

1 Comment so far

  1. Chris Reath on October 9th, 2008

    really really excellent summary. Glad to know my incoherant rablings made sense to someone. Misko at google really said it right. And it’s about time someone said it right. Right?

Leave a Reply