loading...

Things that happen in relationships are the things that matter.

kspeakman profile image Kasey Speakman ・3 min read

You might assume I'm going to talk about fluffy philosophical things. But this is about designing solutions in code. It is a distilled version of conversations with my team.

Let me start with a critique of Object-Oriented Programming... or at least the way it was sold to me. "Model your solutions with objects like in the real world." Wait up... most objects in the real world have no behaviors. A hammer doesn't have a behavior but rather a configuration (weight, head shape, etc). A hammer doesn't become interesting until it enters into a relationship with another object. A builder swings the hammer. The hammer strikes a nail. The nail is driven into a board. And so forth.

In perhaps a more relate-able example, let us think about a student who needs to register for a course at college. How should we code this? Should it be student.Register(course) or course.Register(student)? This is an utterly cliche kind of question that every OO programmer eventually must stumble over. Because OO naturally inclines you by its very name to focus on objects. Both of these alternatives makes the code awkward. (Which is why the question is asked in the first place.) We have missed the fact that the relationship between student and course has a life of its own. It is in fact a process with a defined beginning (registration) and end (completion, withdrawal, etc) -- it has all the interesting behavior. The end result of these processes are the important things that we report on (transcripts, for example). The Student and Course are little more than data buckets where we can throw display data (names, codes, etc) and configuration (prerequisites, corequisites, etc).

So the thing we care about tracking during the semester is the relationship between Course and Student (attendance, homework, exams, etc). However, this relationship is hard to label with a noun. It literally is "the process of educating a student in a course of study". Rolls right off the tongue. You could lego-name it as StudentCourse or CourseStudent (as someone with relational database experience might), but this is not very descriptive of what process you are trying to represent between those things. I would probably settle for EducationProcess as a moniker. This makes a lot more sense: EducationProcess.Start(studentId, courseId, semesterId).

What about appliances?
You could point out that appliances are examples of objects in the real world that have behavior. Quite right, and I submit to you that appliances are actually processes (machines) which manage the relationship between your normal, non-behavioral objects. You put soap and clothes (and water line and electricity) into a clothes washer, and it introduces and manages a relationship between those things for the purpose of cleaning your clothes. That way you don't have to manually introduce that same kind of relationship with a washboard and tub and physical exertion. If this problem were solved using a typically OO strategy of putting behavior on a noun, we would have ended up with very awkward-to-wear self-washing clothes. shirt.Wash(); 😆

The point being that real world objects by themselves are not interesting. The relationship between different objects... that is where all the interesting stuff occurs. That is usually where the business makes its money. At least it is something to consider as you are designing solutions.

/∞

Posted on by:

kspeakman profile

Kasey Speakman

@kspeakman

collector of ideas. no one of consequence.

Discussion

markdown guide
 

Interesting read, thanks! In many cases you have to choose, which object will have more behaviour and which is more anemic. Student.attend(lesson), lesson.add(student). It feels very awkward most of the time.

 

I believe that if it feels awkward, then probably there is a better way to model it. The key take-away here is that where there is confusion about which object in the relationship should host the "behavior", then probably the relationship should be its own object which hosts the behavior. Also that not all nouns are objects with behavior... sometimes they are just data.