mardi 3 juillet 2018

relationship that "inherit" another (1:N) relationship

I want a data-structure that supports these specific 1:N relations :-
1#. Human raise 0-N Human
2#. Human has 0-N Dog
3#. Human cultivate 0-N Tree
4#. Dog is a house of 0-N Parasites.

enter image description here

Note:
- State in these relations are all temporary e.g. Human1 may raise Human2, but after a year, Human1 may abandon Human2.
- All objects are inherited from BaseObject and has unique int ID.

In all of the above relation, I want to be able to support these features :-
F1. add relation e.g. human_dog->addRelation(Human* a,Dog* b)
F2. remove relation e.g. human_dog->removeRelation(Human* a,Dog* b)
F3. query all children e.g. human_dog->getAllChildren(Human*)
F4. query all parent e.g. human_dog->getAllParents(Dog*)
F5. check whether a parent has >=1 child
F6. check whether a child has >=1 parent
F7. remove all children for a parent
F8. remove all parent for a child

This can be implemented by std::unordered_map or something more customized quite easily.

Here comes the hard part

I want to mark relation 1#,2#,3# (i.e. all solid lines) as Feed.
It has to support feature F3-F8 in an aggregating style.

For example :-

  • feed->getAllChildren(BaseObject* b) :
    If b is human, it must return all children of raise,has and cultivate of the b.
  • feed->removeAllParent(BaseObject* b) :
    If b is a dog, it will effect like cultivate->removeAllParent(b).

In my real case, there are 8-10 relations and 3-4 levels of such inherit/indirection.
I want to be able to easily inject such aggregation.
For example, it is useful to call :-

void BaseObject::declareForFreedom(){
    feed->removeAllParent(this);
}

Question

What is a data-structure/design-pattern that suitable for this case?

I currently create a custom 1:N relation for 1#-4#, and hard-code every feed's function. It is tedious.
I have banged by head for a few months, but not found any implementation that look elegant.

Aucun commentaire:

Enregistrer un commentaire