The universal catch-all singleton

By uliwitness

Personified application delegate creating objects by cracking eggsOne bad habit I see time and time again is filling up your application delegate with junk that has no business being in there.

Avoid putting stuff in your app delegate.

What is the application delegate?

By definition, the application delegate is a controller. Most model classes are standard Apple classes. Those that aren’t are slightly smarter collections of these classes. Most view classes just display the model and forward a few IBActions to the controller in a dynamic way, so are inherently reusable as well (even if not always the particular arrangement of their instances).

The controllers, on the other hand, aren’t really reusable. They glue all this stuff together. They’re what makes your application your application, along maybe with a few bindings. So, again by definition, the application delegate is the least reusable part of an application. It’s the part that kicks everything off, creates all the other controllers and has them load the model and views.

Reusability is best!

The whole point behind OOP was to reduce bugs, speed up development, and help structure your code by keeping it grouped in reusable components. The best way to maintain this separation of components and permit re-using parts of it in different projects, is to keep the boundaries between components (e.g. objects) clean and distinct.

Objects have a clear hierarchy. The top creates objects lower down and gives it the information they need to operate correctly for your application. Nobody reaches up the hierarchy, except maybe to notify whoever created it of occurrences in the form of delegate messages. That way, the more application-specific your code gets, the fewer other objects know about it. The further down you get, the more reusable.

Moving operations or instance variables that are shared by several objects in your application into the application delegate, and having other objects reach straight up through NSApplication.sharedApplication.delegate to get at it, goes head-on against this desire, and turns your carefully separated code into an inseparable glob of molten sludge. Suddenly *everybody* includes the most application-specific header your application contains.

Don’t lie to yourself

The application delegate is one of the singletons every application contains. Its name is misleading and fuzzy. If you see it as a place to hold code “relevant to the application as a whole”, there is pretty much nothing that is off-topic for it. It is the universal, catch-all singleton.

So why not be honest to yourself: Whenever you add code to the application delegate, and you’re not just doing it to react to a delegate method from NSApplication and create a controller to perform the actual action in response, what you are really doing is create a singleton.

As we all know, singletons have a use, but having many singletons is a code smell. So avoid them if you can, but if you feel you can’t, be honest to yourself and actually make it a separate singleton (or find one whose purpose these operations fit).

Just say no to the application delegate as the universal singleton.

Update: If this hasn’t convinced you, here’s another blogger with a more CoreData-centric discussion of the issue, coming to the same conclusion: Don’t abuse the app delegate.