Manager classes can be a sign of a bad architecture, for a few reasons:
Meaningless Identifiers
The name FooManager
says nothing about what the class actually does, except that it somehow involves Foo
instances. Giving the class a more meaningful name elucidates its true purpose, which will likely lead to refactoring.
Fractional Responsibilities
According to the single responsibility principle, each code unit should serve exactly one purpose. With a manager, you may be artificially dividing that responsibility.
Consider a ResourceManager
that coordinates lifetimes of, and access to, Resource
instances. An application has a single ResourceManager
through which it acquires Resource
instances. In this case there is no real reason why the function of a ResourceManager
instance cannot be served by static methods in the Resource
class.
Unstructured Abstraction
Often a manager is introduced to abstract away underlying problems with the objects it manages. This is why managers lend themselves to abuse as band-aids for poorly designed systems. Abstraction is a good way to simplify a complex system, but the name “manager” offers no clue as to the structure of the abstraction it represents. Is it really a factory, or a proxy, or something else?
Of course, managers can be used for more than just evil, for the same reasons. An EventManager
—which is really a Dispatcher
—queues events from sources and dispatches them to interested targets. In this case it makes sense to separate out the responsibility of receiving and sending events, because an individual Event
is just a message with no notion of provenance or destination.
We write a Dispatcher
of Event
instances for essentially the same reason we write a GarbageCollector
or a Factory
:
A manager knows what its payload shouldn’t need to know.
That, I think, is the best justification there is for creating a managerlike class. When you have some “payload” object that behaves like a value, it should be as stupid as possible so that the overall system remains flexible. To provide meaning to individual instances, you create a manager that coordinates those instances in a meaningful way. In any other situation, managers are unnecessary.
Of course, mangers can be good. An obvious example is an EventManager
explains it all right there. A misuse of the concept is bad architecture, but there are legitimate use cases. The same holds true for most anything.EventManager
is a horrible name for a class. It ostensibly does something with events, but what?