Code Design – How to Avoid ‘Managers’ in Code

cclassdesigndesign-patternsentity-component-system

I'm currently re-designing my Entity System, for C++, and I have a lot of Managers. In my design, I have these classes, in order to tie my library together. I've heard a lot of bad things when it comes to "manager" classes, perhaps I'm not naming my classes appropriately. However, I have no idea what else to name them.

Most of the managers, in my library, are composed of these classes (although it does vary a little bit):

  • Container – a container for objects in the manager
  • Attributes – attributes for the objects in the manager

In my new design for my library, I have these specific classes, in order to tie my library together.

  • ComponentManager – manages components in the Entity System

    • ComponentContainer
    • ComponentAttributes
    • Scene* – a reference to a Scene (see below)
  • SystemManager – manages systems in the Entity System

    • SystemContainer
    • Scene* – a reference to a Scene (see below)
  • EntityManager – manages entities in the Entity System

    • EntityPool – a pool of entities
    • EntityAttributes – attributes of an entity (this will only be accessible to ComponentContainer and System classes)
    • Scene* – a reference to a Scene (see below)
  • Scene – ties all the managers together

    • ComponentManager
    • SystemManager
    • EntityManager

I was thinking of just putting all the container/pools in the Scene class itself.

i.e.

Instead of this:

Scene scene; // create a Scene

// NOTE:
// I technically could wrap this line in a createEntity() call in the Scene class
Entity entity = scene.getEntityManager().getPool().create();

It would be this:

Scene scene; // create a Scene

Entity entity = scene.getEntityPool().create();

But, I am unsure. If I were to do the latter, that would mean I would have a lot of objects and methods declared inside my Scene class.

NOTES:

  1. An entity system is simply a design that is used for games. It is composed of 3 major parts: components, entities, and systems. The components are simply data, which may be "added" to the entities, in order for the entities to be distinctive. An entity is represented by an integer. Systems contain the logic for an entity, with specific components.
  2. The reason I'm changing my design for my library, is because I think it can be changed quite a lot, I don't like the feel/flow to it, at the moment.

Best Answer

DeadMG is spot on on the specifics of your code but I feel like it misses a clarification. Also I don't agree with some of his recommendation that don't hold in some specific contexts like most high performance-videogame development for example. But he's globally right that most of your code is not useful right now.

As Dunk says, Manager classes are called like this because they "manage" things. "manage" is like "data" or "do", it's an abstract word that can contain almost anything.

I was mostly in the same place than you around 7 years ago, and I started to think that there was something wrong in my way of thinking because it was so much efforts to code to do nothing yet.

What I changed to fix this is to change the vocabulary I use in code. I totally avoid generic words (unless it's generic code, but it's rare when you're not making generic libraries). I avoid to name any type"Manager" or "object".

The impact is direct in code: it forces you to find the right word corresponding to the real responsibility of your type. If you feel like the type does several things (keep an index of Books, keep them alive, create/destroy books) then you need different types that each will have one responsibility, then you combine them in the code that uses them. Sometime I need a factory, sometime not. Sometime I need a registry, so I setup one (using standard containers and smart pointers). Sometime I need a system that is composed of several different sub system so I separate everything as much as I can so that each part do something useful.

Never name a type "manager" and make sure all your type have a single unique role is my recommendation. It might be hard to find names sometime, but it's one of the hardest thing to do in programming generally