The first time I look at a legacy project, I scan for warning signs. I’ve covered singletons, excessive observers, and today I’ll talk about “Manager” classes.

I have to reiterate these are guidelines, not rules, and among guidelines, this one isn’t critical. A Manager here and there warrants an audit when it’s time to refactor. But if you’ve got dozens of classes like LoginManager, CacheManager, and DataManager, you’ve probably got architectural problems.

The Symptoms

Managers can be a symptom of poorly-defined responsibilities. When you think about it, the word “Manager” means nothing. In object oriented programming, every class is a manager. Cocoa Touch could have UIApplicationManager, UIViewManager, and even a humble NSStringManager.

Like the real world, the worst managers start with good intentions. Say your AvatarUploadController is over 3,000 lines long, and most of it deals with, like validating image dimensions, resizing it, uploading it, checking for network errors, and so on. If you cut and paste code into another class and call it AvatarManager, it’s progress.

Now take a step back and ask why “massive view controllers” are a problem. It’s the Single Responsibility Principle. Every class should be responsible for a single bit of functionality. Small view controllers are good, but I can live with a massive view controller so long it only handles view controller stuff, like setting up view hierarchies and responding to adaptivity changes. When your controller handles networking, you’re in for trouble.

Extracting tons of business logic into a AvatarManager solves the immediate problem. If we’re talking fifty lines of code, maybe that’s enough. But if you’re dealing with thousands of lines of business logic, wrapping it in a Manager is a half-measure. You cleaned up the mud in the living room by sweeping it into the kitchen.

On the other hand, managers can be a symptom of faux object oriented design. Consider NSFileManager, which is really just a collection of file functions. In a true OO design, rather than call removeItemAtURL(), you might instance an NSFile() object with a URL, and then call its remove() method.

That’s not to say all code needs to be object oriented, but NSFileManager does a disservice by faking it. Its uses a singleton, defaultManager, so there’s a risk of someone (probably a random third-party library) assigning to its delegate property, and messing up file operations for the whole app. Is this really better than a loose collection of file functions?

How to Fix It

I can already see junior engineers clicking the “Refactor” button, ready to swap Manager with Broker, Coordinator, Utility and so on. That’s the problem with rules: jank finds a way.

When you audit a Manager class, ask, “What is this class responsible for?” If you have trouble answering that, ask, “Can I break it down?” In the avatar upload example, I’d pull out a NetworkAPI, ImageValidator, ImageConverter, etc.

Managers aren’t a big red flag because it’s an easy noun to fall back, even when you know what you’re doing. If a senior engineer sits at a screen for too long thinking of a name, their “you’re being too clever” sense kicks in. You don’t want to be that amateur who waxes on about aesthetics while shipping nothing.

Even Apple frameworks use the noun, like Core Location’s CLLocationManager. Hey… let’s audit that class?

What are its responsibilities? It tracks changes to the user’s location. Does it take on too many responsibilities? I don’t think so. I’d be worried if it included unrelated stuff like reverse-geocoding.

Ok, can we rename the class to clarify things, and fight responsibility creep? I’d go with CLLocationObserver, or CLLocationTracker. Nice!

Except Apple would be nuts to rename CLLocationManager this late in the game. Too much legacy code depends on it, and even if you built code-migrators to help, it’s hard to justify wasting time on this when you could be delivering features to users.

But if you’re building something to last, or building any sort of dependency, it’s worth spending an extra few minutes to name things right the first time.