Question about Managers

Started by
38 comments, last by Serapth 12 years, 5 months ago
I've read a few times on this forum that the use of any kind of Manager is frowned upon; in fact, I think I even read somewhere here that if you feel the need to create a class with the word Manager in the name then you're design is wrong.

In the case of a state machine, to me anyway, it kind of makes sense to have a state manager class to handle all the different states and their initialization, queuing, cleanup, etc. Am I wrong in this, or would this be an appropriate place to have a manager?

Oh, and in my game I'm creating right now I've made an asset manager, or resource manager class that handles loading resources from a custom file format into memory and makes for easy retrieval of the needed resource via a simple function call and ID string; is this bad design as well?

Thanks
-akusei
Advertisement
Manager's very much have their time and place and if anyone blanket tells you "never use X or Y" generally you should disregard their opinion, unless of course they said to never us DevC++, because you should never use DevC++. :)


Managers can be quite useful, the pitfall is quite often they are just globals by another name. Then again, sometimes globals can be quite useful too and many times you will hear people say "NEVER USE GLOBALS!", which is rather idiotic, but has a kernel of truth to it. Lets go with "Never use globals, unless they are the best option". The same can be said of Manager classes. Some times it does make sense to have a global manager class of some shape or form, such as your described state machine, you just have to be careful you aren't just creating managers out of lazy design... because they are (initially) easy.


You just have to be extremely careful. On of the issues with using global or manager classes is they touch so many areas of your code, that finding a bug or making a change can be an absolute nightmare. In this regard, make sure ( if you can help it ) that your manager is basically a black box. If any class can effect changes on your manager, you can create an absolute friggin nightmare if you need to bug hunt later. In this case, do your best to make any global/manager classes as tight as possible with the bare minimum number of externally accessible methods. If there is a need to make changes to a manager class, doit through a very narrowly defined interface. Also be sure that the manager always owns everything it requires. Don't ever let an external process destroy or alter something the manager owns, without the manager being explicitly aware of it, preferably by only returning const values. Finally be very careful in regards to thread safety.
In addition to Serapth's answer:

If you're a beginner, then I would say do what you think is a good way to solve the problem. There's a difference between reading that you shouldn't do something and doing it to see where things go wrong so you can actually understand why you shouldn't do it, and in what exceptional cases you can use that solution.
I think the reason for the advice you have heard is less to do with globals (this is a valid but different issue) and more to do with the fact that responsibilities of a Manager class tend to grow due to the vagueness of the term.

If a class loads and stores resources, say, this is probably a good candidate for splitting into two, each with its own clear responsibilities. This makes for a system that is cleaner to extend with new types of loader for example.

When a class name becomes vague, the temptation to blur its responsibilities increases.

When a class name becomes vague, the temptation to blur its responsibilities increases.


class ManagerManagerManager
{
LightManagerManager LightManager;
ObjectManagerManager ObjectManager;
};
As mentioned above, manager classes are usually bad because they have very vague responsibilities. In a good design, each class should have only one well defined responsibility. Once a class starts taking on multiply responsibilities, it should be split into multiple classes and then composed together.
When a class gets "manager" in it's name, it's usually a hint that it has a lot of responsibilities -- this isn't always the case, but it's true often enough that now "manager" classes are usually treated with suspicion.
In the case of a state machine, to me anyway, it kind of makes sense to have a state manager class to handle all the different states and their initialization, queuing, cleanup, etc. Am I wrong in this, or would this be an appropriate place to have a manager?
[s]class StateManager;[/s] [font="Courier New"]class StateMachine {[/font]
private:
[font="Courier New"] StateContainer m_container;//responsible for init/cleanup[/font]
[font="Courier New"] StateQueue m_queue;//responsible for queueing[/font]
[font="Courier New"]};[/font]
Oh, and in my game I'm creating right now I've made an asset manager, or resource manager class that handles loading resources from a custom file format into memory and makes for easy retrieval of the needed resource via a simple function call and ID string[/quote][s]class AssetManager;[/s] [font="Courier New"]class AssetRepository;[/font]
Make those changes and you're no longer using "manager" classes cool.gif
Thanks everyone for the input, as usual it was very helpful!
-akusei
out of curiosity how do you guys feel about manager classes in data oriented design rather than object oriented design? A better name might be calling it an interface with the data, but as interface already has a pretty well defined definition in most programming, you can't really call it that.

out of curiosity how do you guys feel about manager classes in data oriented design rather than object oriented design? A better name might be calling it an interface with the data, but as interface already has a pretty well defined definition in most programming, you can't really call it that.


If you work(ed) in corporate IT in n-tier solutions, this is very much the norm. The name is generally the DAL ( Data access layer ), which is essentially a thing abstraction above the application data. In a typical 3 tiered approach you have your view or presentation layer, your business logic layer ( BLL ) and your DAL. The DAL is an abstraction of the data, the view is your UI and then your BLL is your logic.

It actually applies fairly well to gaming too, especially if you want your tools and game to share the same code.
out of curiosity how do you guys feel about manager classes in data oriented design rather than object oriented design?
There's actually a great example of this in most game engines (even heavily OOD ones) -- particle systems.
Usually it's realised that treating every single particle (when there may be millions of them) as an independent object isn't the best approach, and instead they're managed as a "system" of particles instead.

I'd still avoid calling it a 'manager' if you can, to properly define the responsibility of this 'grouping' class.

This topic is closed to new replies.

Advertisement