views:

61

answers:

1

I have a couple of base/interface classes each of which has several derived classes. I have a need to store metadata on each derived class that has a lot of overlap, but different values.

I also have a Factory class for creating instances of the derived classes that's implemented as a singleton and has a few macros. For example, you'd:

REGISTER_COMPONENT("MyComponent", MyComponentClass);
// create an instance of each component
BaseComponent *base;
foreach(QString component, ComponentRegister::componentList())
{
  base = ComponentRegister::create(component);
  // do stuff with base
}

The question is: how and where to store the metadata from a solid design viewpoint.

I could store the data in the ComponentRegister as a QMap structure. When someone registers a component, they could also register its metadata with something like

REGISTER_COMPONENT_METADATA("MyComponent", MyMap);

If the QVariant::isValid() for a particular key, you know the metadata is set and available.

Another way would be static class variables or maybe a static class QMap.

I see advantages and draw backs to both. Most of the metadata are things like "path to QResources for this class" which is not tightly coupled to the business logic of the class itself.

Another issue with the static class variable method comes into play with inheritance. You can't enforce overriding of static class variables like you can with pure virtual functions. So if someone forgets...it could be unclear where in the inheritance tree the values are coming from. If you require access to the metadata through a series of pure virtual "getters" then setting of the MetaData is spread across all implementations of the Base class.

With data held, set, and looked up in the Register if you needed to make changes (like changing the root path for resources), you could do so at a single point...in the class registration calls, probably a header or wrapped in a application Utility function. With static data, you'd have to edit each class declaration.

Open to suggestions and thanks!

A: 

If data related to an object isn't specific to a single instance, as the path in your example, my designs usually include a class which manages my collection of objects. That's where I put the meta data.

example:

class zoo { std::vector<animals> zoo_animals; size_t count; }

count is metadata about the animals.

Jay