I sometimes hear that having too many "manager" classes in your program's design is code smell and add an unnecessary layer of complexity. To me it makes sense that people want to use manager classes for manipulating and controlling objects from a context that makes sense to them, but figuring out how to make a solution work without them can be confusing.

Should one really avoid manager classes as much as possible? Also, what articles/papers should I read on how to implement an alternative work around for general/common cases where these managers can be removed?

3 Answers
3

There are maybe two reasons this is a code smell. One reason is, that it may mean you don't have domain objects but instead you have value objects that just store data for manipulation by controller or manager classes. This is actually pretty common and amounts to procedural programming in an OO language. The "lots of managers" may be a hint that you need to integrate state logic, validation and other direct concerns into the domain objects so that they actually encapsulate something. Of course there are bigger hints such as the fact that you have no methods other than getter/setters.

The other reason its a code smell is that it may mean your domain objects don't actually relate to each other very well. For instance if you have an Account class that really doesn't know anything about Transaction class except that it is named Transaction and there can be more than one of them, then you again you don't really have a very vibrant business domain implementation. For example SavingsAccount should maybe know that it can't accept a DebitTransaction if the accountStatus is closed. A lot of implementations would leave this up to the manager.

The biggest problem with Manager Classes is that they only represent this vague idea of what the class is supposed to do. If you call something a Manager then it can do anything and everything possible relating to whatever it is managing. I suppose in some contexts that might be ok, but I would say in almost all cases that is not what you want. You want someone to be able to look at the class name and not only have a darned good idea of what the class does do but also what it doesn't do.

Another problem with manager classes is that it makes it very difficult to decide where functionality should go. When there are a lot of manager classes then there is frequently a lot of overlap in functionality between manager classes. You then have to figure out which class should implement that overlapping functionality and of course someone else would have chosen differently. So when they look for the functionality and don't see it where they expect then they go ahead and re-implement it where they think it belongs because they aren't aware of the other implementation's existence. In other words, manager classes lead to hard to understand and frequently convoluted designs.

Having lots of "manager" classes is often a sympton of an anemic domain model, where the domain logic is hoisted out of the domain model and instead placed in manager classes, which more or less equate to transaction scripts. The danger here is that you're basically reverting to procedural programming - that in itself may or may not be a good thing depending on your project - but the fact that it wasn't considered or intended is the "code smell" imo.

Following the principle of the "information expert", a logical operation should reside as close to the data it requires as possible. This would mean moving domain logic back into the domain model, so that it's these logical operations which have an observable effect on the state of the domain model, rather than transaction scripts changing the state of the domain model from the outside.