Object Composition

Object composition is defined as the methods used when combining simple objects or data types into more complex ones. As definitions go, this is sufficient for Wikipedia, but it doesn’t really tell us much. It’s a topic I am trying to be more deliberate about, in my previous experiences the only developer who read my code was me. Writing code in a way that others who follow can easily understand is something that every book I’ve read in the apprenticeship has justifiably hit on. In my development I keep coming back to these lessons and so this week, I’m going to try to condense several books worth of little details into a compact walkthrough, and maybe it’ll be useful to you as well.

Where do we start?

One of the suggestions I keep seeing for both checking for SRP violations and identifying relationships is to describe your objects and how two related ones work in the simplest sentences you can. For relationships specifically you may find yourself coming up with sentences like “a Child is part of a Family”, “a Tesla is a Car” or “a Department has a University”. The key for this stage is to leave out anything that isn’t one of the objects and the connection as you’d write it, thinking in terms of a child being connected to a parent (if you think in terms of “part of a” or “is a”, “has a” it’s easier but not required). If you’re not sure what the parent should be then the first question to ask is which object is the more generic form, or makes sense to “own” the other? That’s going to be your parent object. Once you’ve broken it down into these sentences, now you’ve got to start translating them into actual designs, which fall into three main types:

Composite Relationship (or “has a”)

The simplest relationship, composite objects typically have a clearly defined parent object such as in our examples a department can hardly be called the parent of a university. With a composite object, the child object doesn’t have a reason to exist without the parent. Consider the university example, creating a Department without having University doesn’t work. Note that the reverse doesn’t have to be true, a University can be created without Departments being defined and the exact list of Departments can change without creating a new University.

Aggregate relationship (or “part of a”)

Next we have aggregates which vary from composites in the lifespan of the child. If the child can exist without being associated with a parent, especially if it can outlast the disposing of the parent, it’s an aggregate. In case you’re not already thinking it, a real life parent/child relationship neatly fits this definition, perhaps they can’t be created without parents but them losing that association doesn’t cause them to cease to exist (did I just reduce human reproduction to a factory object in my head? Possibly) Other than when the child objects are created and destroyed, there may be little difference between this and composite relationships in implementation.

Inheritance (or “is a”)

Last, and trickiest we have Inheritance. The parent is the most generic or basic description of what the hierarchy does, and the children define difference that aren’t shared by all the siblings. This can be costly to fix if you misuse so typically it’s recommended to avoid this unless nothing else makes sense. In fact a common symptom of misusing this is having to modify the parent object when adding a new child object. Even if it is the best option then the ideal way to do it is with a shallow hierarchy, avoiding editing the parent class as well as creating a large number child classes.

A Detailed Example

We’re tasked with creating an entire university course catalog and class schedules in an object-oriented fashion, this includes professors, students, departments and classes. Starting at the top, we know we’re going to have objects representing the University, Departments, Professors, Classes, and Students. We also know that some classes are instruction only and some have labs, and no, this isn’t every relationship, just some key ones.

  • A Department has a University
    The Department doesn’t exist without the University making this a Composite relationship
  • A Professor is part of at least one Department
    Professors don’t cease to exist if the Department closes, nor are they for sure limited to one department, making this an Aggregate relationship
  • A Class has a Professor
    I’d define this as Composite as a class doesn’t exist without a professor assigned to it.
  • Students are part of multiple Classes
    This sentence is a bit tricky because you could swap the parent & child without making it easier to pin down. This made me wonder if there’s an object that our original definition left out and sure enough, we saw the specific instance of a Class as the same as the Class itself. So, we add a Subject object to represent the description and department that you’d see in a course catalog, and change Class to describe the specific instance of a Subject that is attended by Students.
  • Continuing, we’re going to make an assumption that in real life we would want to run past the customer: A Course is either a lab or lecture environment, never both.
    • A Lab Class/Subject is a Class/Subject
    • A Lecture Class/Subject is a Class/Subject
      This certainly looks like inheritance, but because not confident of of my understanding let’s not bake it into the Class or Subject objects, but instead turn a type enum into classes that define the behavior differences. This reduces the consequence of being wrong while still allowing the lecture and lab types filter allowed rooms based on their equipment and workspace requirements.

Our diagram at this point looks like this:

ERD Example

One final point to make is that I’ve had relationships that I couldn’t pin down that I traced back to object names that simply were not descriptive enough. Fixing the name, made the relationship far easier to define.

Leave a comment