Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm hearing conflicting opinions such as:

  • "Dedicated Manager classes are almost never the right engineering tool"
  • "Dedicated Manager classes are (currently) the best way to survive a large project with thousands of resources"

Let's take a classic ResourceManager class that has the following functionality:

  • Loads assets (textures, audio, 3D models, etc)
  • Ensures assets are only loaded once by keeping a cache
  • Reference counts assets to determine if they can be deallocated
  • Hides where the actual assets came from (e.g., could be one file per asset, or all assets in one package file, or assets could even be loaded over the network)
  • Can reload assets without restarting the program, which is extremely useful for the artists working on the game.

Let's also take the "singletons are bad" argument off the table by pretending these ResourceManager objects are not singletons, and instead are passed around via dependency injection.

Then there is the "use a factory" or "call it a factory" argument. My problem with this is that, yes, it is a factory, but it's also a cache and a reloader (for lack of a better word). Calling it a factory doesn't describe it properly, and if I make it a proper factory then where does the caching and reloading get implemented?

I agree that "Manager" classes are often a symptom of bad architecture, but in this particular case how could it be restructured and still retain all of the functionality? Is this a situation where a "Manager" class is actually appropriate?

share|improve this question
2  
Maybe call it a warehouse instead of a factory? :P –  Daniel Oct 3 '11 at 2:33
add comment

2 Answers

up vote 7 down vote accepted

I think the issue is not that this is a bad design. The issue is that the name "Manager" is nondescript, like "Update" and "Process" and "Actor". It is unhelpful to someone attempting to understand this system, and it creates confusion if you ever have other classes that perform some operation on assets.

However, naming things in a way that efficiently conveys their purpose is really, really hard. Most systems are too complicated to be made obvious by their name. The best you can do is try to narrow down what specific idea makes this a class cohesive, and what other classes need to be obviously different, and pick a unique word that kind of fits.

IMHO, the most important feature of a good name is that it is unique within the context that people will see it (the code base), and it is easy to remember. The test should be that can you have a conversation with your teammates who are familiar with the code without having to clarify what you are referring to. This would also help if you ever need to write reference documentation.

Finally, consider that if you can't describe that cohesive idea, it may not be very cohesive. For example, you might separate the caching and referencing counting in an AssetCache, and keep the loading in an AssetLoader. But that really depends how complicated and intertwined the code is.

But if your AssetManager is cohesive enough, and nothing else in your game is AssetManagery, then it might be a perfectly good name.

share|improve this answer
    
The AssetLoader/AssetCache separation isn't a bad idea. –  Tom Dalling Oct 5 '11 at 0:39
add comment

"Do I do this in one place, or do I do it many?"

Loading logic is usually centralised to a single point of access because it tends to be run only at key points in the application, where we are trying to get it out of the way ASAP. This usually takes place at app startup, game level startup, or when player world position demands the loading of a new chunk to keep the experience seamless. Considering this is done as a batch process (whether in one massive chunk or many smaller ones doesn't really matter), it makes sense to have one method or set of methods to call, to kick this process off.

On most platforms, loading is asynchronous, so you actually have little choice but to keep the code flows for loading and other app logic separated, another reason for abstraction of resource management functions into their own class.

Lastly, a few of points to think on:

Resource loading is not run very often compared with eg. game logic, so is it worth adding complexity to your individual game objects to do this? Game objects are usually kept light as possible and are intended only for what is needed during simulation.

Should an object be responsible for it's own creation and destruction? This can cause major headaches during entity management. If you expect an object to perform it's own creation process (including getting resource dependencies) then likewise it will have the responsibility of destroying itself. This can cause dangling/null pointers, so really it has to be managed from outside. See this answer outlining that problem in more detail.


P.S. Aside from the usual "Singletons are terrible" type arguments (which are terribly dogmatic), have you ever seen a good argument against ResourceManagers? "Dedicated Manager classes are almost never the right engineering tool" is no argument at all for this specific case.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.