I know there are LOTS of reasons why you would compose a certain object inside another one. Some schools of thought have made explicit the reasons for architecting a program a certain way e.g. ‘data-driven design’ or ‘domain-driven design’. I’m still a beginner to OOP, and it’s often hard for me to understand why one object should be contained by another. Sometimes, I find myself with an object that seems awesome, and then I get to the point where I realize, “Okay, now I have to put this somewhere?” Is the reasoning behind this similar to where I’d decide put a file on my hard disk?
I have a couple guiding principles for this:
- If it models a relationship in the physical world.
- If the composer has data needed to construct the object.
- If the composed object will be listening to the composer.
What do you look for when you make this decision?
Well, one very simple concept that helped me with this is simply the concept of “has a” versus “is a”. Ask yourself, is the contained object something the containing object has, or is it something the containing object is? If it’s something the containing object has, then containment is appropriate. Otherwise maybe you should be looking at inheritance.
A dog IS an animal, and has a nose, so it’s:
Now this works fine. One “problem” with this approach is that you tightly couple noses and dogs, so sometimes you’ll see things like containing an interface pointer rather than an object, or you might Google “Dependency Injection”. But as the saying goes, “has a” and “is a” is often close enough for government work.
Early on, just try lots of examples and over time it will become natural. If you end up with spaghetti, throw some meatballs at it and try again! 🙂