Search code examples
oopmetadatacode-organization

What are the correct ways to store additional information about class instances?


I'm working on a project where each class usually contains a list of instances of another class. This is repeated on several layers, so Class1 will contain a list of instances of Class2, which in turn will contain lists of instances of Class3 and so on.

I would like to keep each class as independent and stand-alone as possible, so that they can be reused again in different projects.

However, in this architecture, it happens often that classes from the upper layers will need not only to access objects from lower layers, but to store metadata of them, which should not be visible to the associated objects. This happens not only with adjacent layers, but also with layers distant from each other. I was wondering what are the possible correct approaches for this, since I fear that the one I am using now is not the best one.

The solutions that come to mind to me are:

  • For each class, create a wrapper that stores addictional needed information. This is possibly overkill ( we may only need to store a few bits ), and I am not sure how would one apply this concept on distant layers.
  • Create a separate structure which holds the metadata, and keep pairs of object instances and metadata-structure instances. Again, not sure on how to use this with far layers.
  • Create public members in the lower classes, that they cannot see/use and that are only used by higher level classes. This solves the problem but I think it is extremely bad practice, and heavily relies on outer code to be nice and not "touch" the metadata.

What are other possible solutions?

Just as an addictional information, I am coding my project in C++, but this shouldn't really related to my question.

EDIT: This is an example to better explain what I mean:

Suppose we have class A and B, which are completed and stand-alone classes. Then we have class C, which is a manager of collections of instances of class A. To do so, it needs to store addictional information about each instance of A it is managing.

Moreover, we have class D, which contains both an instance of class C and a collection of objects from class B. This last class needs to be able to associate each instance of class B with one of the instances of class A (which are managed by its controlled instance of class C), and vice versa.

Where and how would the information needed by C and D be stored in this example?


Solution

  • I think your general problem is you want instances of A and instances of B plus extra meta data for each. So have a WrappedA and WrappedB class with holds a reference to A, plus maintains whatever meta data you need.

    Public class A
    {
    }
    
    public class WrappedA
    {
         private A _underlyingInstance;
         public WrappedA(A instanceToWrap)
         {
              _underlyingInstance = instanceToWrap;
              SetAdditionalMetaData();
         }
    
         protected SetAdditionalMetaData()
         {
              //use _underlyingInstance to set meta data
         }
    }
    

    Then, instead of having a List of Type A have a List of Type Wrapped A.

    public class C
    {
         private List<WrappedA> _myAs = null;
         public C(A[] rawAs)
         {
              _myAs = new List<WrappedA>();
              foreach(A a in rawAs)
              {
                   _myAs.Add(new WrappedA(a);
              }
    
         }
    }
    

    Whatever methods you need to add to your wrapped class, do it. If you need to store special info about AXB, it seems like it would be Ds responsibility for that. D could create a Dictionary with [A_B] as a key, and then store whatever data you want about that combination of AXB in the value.

    Hope that helps.