Classes which manage their own instances.

Started by
4 comments, last by AsOne 18 years, 9 months ago
Hello everyone, I'll get right to my question. Usually when I have an interface of some sort that other classes derive from I create a separate manager class which has add and remove functions, and an update function which will run the update functions of the objects it holds. However, I read about a design pattern called auto lists which basically keeps track of all it's own objects, which got me thinking that, separate classes for management aren't really needed that much. For example:

template <typename T>
class TAutoList
{
  private:
    static std::list<T> objects;
  protected:
    virtual void update() = 0;
  public:
    TAutoList(); // add itself to list
    virtual ~TAutoList() // remove itself from list
    static void updateAll(); // call update function for objects in list
};

class CWhatever : public TAutoList<CWhatever>
{
  private:
    void update();
}

this way I can just call CWhatever::updateAll() instead of writing another class to do the same. I've heard some say a class should manage its own instances while others say that manging itself and its instances are to completely different tasks. So my question is ... When would this design be a particularly good idea, or a particularly bad idea? Thanks.
Advertisement
Standard caveat: I am no expert, what follows is merely opinion.

Good idea:

When you're positively, absolutely, guaranteed to only ever need an update function, and that multiple types really need this sort of update.

When it's not really a list, but some sort of simple per-type property being stored along with the class, and guaranteed to always apply to every instance of that class, ever.


Bad idea:

Every other time.



In my experience, having the seperate classes makes the code easier to follow. It allows the 'manager' portion to be extended or replaced more easily.

In my experience, auto-managing doesn't promote code re-use any more, since the 'manager' parts will likely be derived from, or a templated instance of, common code anyways. The static-ness is fairly restrictive to design, since it's not uncommon to need two manager instances [even for the same type].
Hmmm...

I would not use the autolist "pattern" for updating or "behaviour" functionality. I always come across special cases where either the update interface is broken (for example feeding different parameters to different objects) or the update should not be called on every created object. Pooling stuff for avoiding memory allocations could be one such thing, some objects should be updated others not.

I would, howerver, use it for doing other things where i definitely need a way of knowing all instances of an object. For example persistance (saving all created objects).

Not that easy to answer :P

Hope I gave you something to think about :)

Regards,
hObbE
-------T.W.T.P.B. stylized shoot 'em up game - Get it now while it's hot!
Ask yourself this:

Would there ever, ever, EVER be an instance in which you'd want an instance of your class that was not in the list? Say, to backup data for a possible undo, or as a copy that is temporarily modified in a function, or as part of a prototype pattern, or as a temporary during a swap, or....?

If so, then you shouldn't use this. It is a really bad idea where the list represents inclusion or participation in a group. For instance, if you had a class representing a character, and a list of characters in the game that you could update AI on, you would NOT want to have the mere creation of a character place it in a scene.

Additionally, I don't really like this pattern as an alternative to "Library" classes; it obscures the actual functioning of the library.

What is your particular application?
That will work until you start having objects spread out across executable modules (such as DLLs). Then you'll have more than one static list of objects. Oops! Additionally using any sort of global data makes thread-safety more difficult, and re-entrancy problems can crop us as well.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
So I should probably only use this to manage a limited number of types of objects, that I know for sure will only need to be updated with a single function.

Quote:
What is your particular application?


Not anything specific yet, I just noticed this approach was used in the Enginuity series to manage garbage collected objects.

This topic is closed to new replies.

Advertisement