C
C#2w ago
Giogio

Tree structure vs composition

Trees are common in the application I currently develop. For example there is a tree of machines, where machine has a parent (machine family), the parent can have it's own parent and so on. Both machine and machine family can have parameters, these parameters are inherited from parents, so if a root parent has parameter A, the second parent has parameter B then machine will also contain parameters A and B. There is a lot of business logic attached to these parameters and the problem for me is 1) loading this whole tree structure from the database 2) iterating through parents for parameters. I started wondering, maybe composition will be a better approach. That means that instead of having parent, machine would have a list of parents with indexes (levels). So instead of this Machine A └── Parent 1 └── Parent 2 └── Root parent I would have this Machine A ├── Parent 1 (index = 0) ├── Parent 2 (index = 1) └── Root parent (index = 2) Then loading all parents and parameters wouldn't be a problem AND iterating through parent's parameters would be easier as well. Question: What do you think of this, are there hidden problems that I don't see? I never encountered structures like this so I'm a little nervous to implement that. Some context: - Leaf rarely has more that 3-4 parents - Item is used either by itself or with every parent recursively
4 Replies
always say never
my 1.9 cents: is db just storage or do you need to execute other queries? db model doesn't have to be same of domain model, you could store them flattened and recreate this tree after having read it PS yeah kinda like the second solution you shown, although i would have used a structured key and made a dictionary PPS pardon me but "leaf rarely has more than n parents sounds like a graph, not like a tree in the end it depends how you use this, how you access the fields and what the parents matter in all this business
Giogio
GiogioOP7d ago
Thanks for the answer. Db is used only for storage, no specific queries are used. About separating db and domain models, I use ef core code first, so I think it's not feasible. Can you share more about making keys you mentioned in P.S. You're talking about making parents a dictionary where level of the parent is the key? Probably as you mentioned "leaf" is not a lucky term for this case, but basically I meant that the depth of the tree is rarely exceeds 4-5.
always say never
About separating db and domain models, I use ef core code first,
but you will still access db through a class/service/repo of some sort
You're talking about making parents a dictionary where level of the parent is the key?
to me it could be a string (like parent1:parent2:parent3, or even a json like ["parent1","parent2","parent3"]) , or a vector, or a struct depends if you need that data and eventually in which way for example if you need to worry about uniqueness when adding a leaf, if you need all nodes to be updated when a name changes, or what else
SleepWellPupper
You could totally implement the flattened version in ef, and map that to the domain model using the tree structure. If your tree is not expected to be too deep, I would not bother though. Inadvertently retrieving all the parents when only the leaf is required seems like an issue in both models. I would go with the model that is more intuitive in terms of the domain. To me, that seems to be the tree structure. Are these models accessed very frequently? If not, would always retrieving the full branch be really a performance/usability issue?

Did you find this page helpful?