Objective-C Singletons – an alternative pattern

Singletons are supposed to be bad practice in any programming language. One of the arguments against their use is that they are difficult to re-use, they hide dependencies, they’re hard to sub-class, and loads of other reasons that I can’t remember since I fell sleep reading them…

Bullshit. There are clear cases where a Singleton makes sense, for instance when you are only ever going to use one instance of a class – for example an application’s data model. The key is to make your singleton re-usable and interchangeable and to provide a fa├žade to the implementation by means of an interface – “write to the interface”. This ensures that the class is not really a Singleton, but that you are accessing a single default instance of the class. This is a subtle difference.

Here’s the canonical way of declaring a Singleton in Objective-C:

The dispatch_once call ensures that the instantiation is thread-safe. That’s it. It’s limited but it works. However, this pattern is the one that the critics shoot down. Here’s a better pattern…

We’re going to create a re-usable Data Model Manager class (DataModelManager) where we can access just one instance (the Singleton), via a Factory class, of an implementation of an Objective-C Protocol and still have the freedom to swap out the implementation if needed (and sub-class, too).

Here’s the Protocol for the Data Model Manager and the Interface that will serve as the factory class:

Any required instance methods for the Data Model Manager should be declared in the Protocol. This is equivalent to a Java Interface. We are declaring those methods that any implementation of the DataModelManager protocol has to implement (required). The DataModelManagerFactory interface returns the (Singleton) shared instance of DataModelManager. The implementation is opaque to the user, and is in fact interchangeable. What we have declared so far is the public API. The consumer doesn’t need to know any more than that.

Here’s the implementation:

We’re using the same traditional Singleton pattern as before, except that we’re declaring the class name of the actual implementation of the DataModelManager protocol in an NSString. This could be declared and retrieved from an external configuration file, or passed as a parameter to the DataModelManagerFactory when initialising. Or hard-coded if you ever need to refactor and provide a different implementation of DataModelManager.

Here’s the interface declaration and implementation of TheDataModelManager:

If we want to swap out a different implementation class, all we need to do is change the name of the class string in the Factory and provide a matching implementation class of the same name. So if we changed it to this:

We would implement it differently:

This pattern ensures that you’re not locked in to a single, static implementation of your Singleton. As the consumer, you only care about the methods that the Singleton declares in its Protocol. The actual implementation can be changed both at compile time and dynamically at run-time if the name of the class is provided to the Factory class. And, as a bonus, it’s easy to substitute a mock class for unit testing.

Let’s modify the Factory class so we can change the class name:

Now we can initialise the DataModelManagerFactory with the class name of our mock DataModelManager class, “MockDataModelManager”:

All we need do now is implement the MockDataModelManager class.

There’s refinements that could be made to this pattern, and improvements. For example, you could pass a Class type instead of a Class string. It’s the basis for a useful pattern.

You could argue that it’s not really a Singleton pattern at all, but that you are declaring a single access point (the sharedInstance factory class method) to an instance.

6 thoughts on “Objective-C Singletons – an alternative pattern

  1. Nice article, and good to see I’m not the only one thinking that saying singleton are bad is real bullshit.

    That being said, when making real singleton classes in Objective-C, you should also ensure the alloc method can’t be used to create a new instance, by making it return the single instance. And of course, you should override release, retain, etc.

    Anyway, thanks for that article. : )

  2. Right, thanks for that. I think the idea needs more work. I even played with using your Class cluster idea to implement it. I think I was just trying to counter the “Singletons are bad” people.

  3. Nice article. Came across this when looking into why singletons are bad. I am thinking of making one of my classes a singleton instead – its the data model so to speak. Holds info about the user and app state. Singleton would really work well in this case – but I don’t know if it is the right way of doing it.

    • If you’re only ever going to use one instance, why not. As I said, it’s only the instance of the class that’s a singleton, accessed from the class itself for convenience, rather than handing the instance on between classes. If you ever only have one instance of a data model, which class will be the “owner” of it? Not AppDelegate! So why not make it the class itself?

Comments are closed.