Yesterday I published an article asking Cocoa developers to rethink a common “Singleton” pattern and to improve it for our sanity:
I recommend hiding the
sharedWhateveraway from clients of your API. You can still just as easily have a shared, static instance of your class, but there’s no need for that to be public. Instead, give your class’s consumers class methods to work with.
I received three kinds of feedback for this article, the first kind being agreement, and that’s all there is to say about that.
The second theme was “It’s not the convention in Cocoa”. I think the reason for this is most of the time, developers are confusing a similar but different pattern used in Apple’s frameworks. The most common example is
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:SOLUsesStringConstants];
This looks a lot like a singleton but it isn’t. It’s just a way to access the
standardUserDefaults, a pre-made object which your app will likely want to interact with. But it in no way implies or means you can’t create your own. The same pattern applies for other classes like
NSFileManager to name but a few.
The third bit of feedback is where I’m a bit foggy, and that’s about the testability of hiding the shared object. I don’t do unit testing very often, but when I do I haven’t run in to any issues. From a fundamental point of view, I don’t understand why hiding the shared object should make testing any more difficult (I’m not being coy or shitty, I legitimately just don’t know). As far as I can tell, you’ll still be testing the public interface of your class, and that should be enough. But if I’m missing something (and this is entirely likely) then I’d love to know about it. Write about it on your website or email me.