For objects in some hierarchy, what is the best practice for parent-child methods/properties that define the relationship? (ALT: is the arm-bone connected to the hand-bone, or vice versa?)
11 views (last 30 days)
I think it is best to begin with an example that uses human anatomy as a metaphor; we will begin with two classes. Lets call one forarmClass, and the other handClass. Each class has its own unique set of properties/methods (although they may both be sub-classes of something like tissueClass that defines how cells and veins work). Lets have an instance of each (Hand, and Forearm). These instances are linked, and I will choose a parent-child relationship with the object closer to the torso being parent; Forarm > Hand.
I now want to calculate values that depend on properties of both Forerarm and Hand, as well as properties of the linkage between the two which I shall call Wrist. Note that I do not want Wrist to be its own object, since that just extends the problem to Forarm > Wrist > Hand, which now requires two sets of linking properties/methods; Wrist is (for now) just a stand-in for the relationship between Forearm and Hand.
So, there are characteristics associated with Wrist, such as a 3-element representation of the rotation of the wrist. If I want to figure out where Hand is in the world, and what its orientation is, I will generally need to incorporate
- Properties/methods of the child object Hand, including its geometry (where is the origin relative to the pivot point of the wrist?).
- The position/orientation of the parent object Forearm.
- Characteristics of the Wrist (its rotation).
So, should the properties/methods of Wrist belong to:
(A) Forearm - the forearm is the parent and has access to all of the information about itself, and can pass that information along as necessary to its children.
(B) Hand - the hand is what actually needs to know the properties of the Wrist to figure out where it is: if there is no hand (Luke Skywalker), there is no parent-child relationship Wrist, but the Forearm is unaffected since it can function without ever needing to talk to the Hand.
(C) Wrist - no, really you should make a wristClass to control the relationship between the two. After all, information about location will normally flow outwards from the torso, but occasionally you may need information to flow from wrist > forarm if, for example, somebody gives your hand a vigorous shake. An independent wristClass lets you work on this two-way flow. You could make two superclasses bodypartClass and jointClass to represent objects and links (Ok, but how then does the parentage work?)
Are any of these best-practice for this kind of problem?
I know that this is a common issue in solid-body mechanics for video games in e.g. Unity, but that is assembling things at a much higher level than what I am trying here. The solid-body anatomy metaphor was just the easiest to use, but you could substitute something more abstract (e.g. a hierarchical database) or literal (e.g. a proper family tree: 'siblings' is a property of children, but are dependent on the parent. where should that info/method live?) I also acknowledge that my metaphor may be too simple, and that the actual answer is highly case-dependant; however, I would like to know if anyone has suggestions/references.
TLDR: I have a heirerarchy of objects, should to the parents or the children control methods/properties of the parent-child relationship, or should I have another class that governs the relationship?
Steven Lord on 14 Jun 2019
In your hierarchy, do you inherit or compose? In this case composition (having the Forearm object contain a property that isa Hand object) seems more appropriate than inheritance. A Forearm hasa Hand, a Forearm is not substitutable for a Hand nor is a Hand substitutable for a Forearm. Neither isa instance of the other class.
Since each of these are likely a handle object you could probably give the Hand a property that is the Forearm to which it is attached and vice versa. If the Hand needs information about the Forearm to which it is attached, it asks. If the Forearm needs information from the Hand, it asks.
You might need to be careful when it comes to traversing the list of body parts not to get yourself in a loop, and you might (though I haven't thought it out in detail) need to create saveobj methods for the objects. Alternately you could have a Body object that keeps track of all the objects and their connections, and have queries from Forearm to Hand and vice versa go through the Body. This might allow you to generalize, instead of having a Forearm class you might have a Limb class that's attached to an Extremity and to a Torso.