Law of Demeter
Aka “don’t talk with strangers”, this law wants us to always keep the lowest coupling possible between objects, and enforce encapsulation to hide implementation details.
Hello, developers! 🚀
Welcome back to the Learn Agile Practices newsletter, your weekly dose of insights to power up your software development journey through Agile Technical Practices and Methodologies!
Before starting, here are some quick news from the Learn Agile Practices ecosystem:
A free webinar about TDD is coming next week, on Friday 24th at 5 pm CEST! I will introduce the practice, making sure you avoid the usual mistakes and misconceptions that most people fall into, in a free 1-hour session! Book your free session 👉 here(or feel free to pay what you want!)
Lifetime Deal of the Week 👉 AI2SQL - An AI tool that allows you to easily create complex queries with just a few clicks, without writing any SQL. Get a lifetime license for just $59 here (referral link)
Now, let's dive into today's micro-topic!
Communicating through messages it’s not enough
This week, I will go further into the same starting point I used last week: Object-oriented programming is full of misconceptions and mistakes that spread everywhere over the years and decades. Last week, I focused on the kind of misconceptions related to how we transform data in an OOP system - this week, I want to focus more on those related to how objects encapsulate their behavior and how they communicate with each other.
Once again, let’s start from the original definition of Object Oriented Programming:
A system made of objects that communicate with each other through messages.
Messages in the OOP context mean the public methods that every class exposes to the outside: those functions are the only way every object should offer to the outside to interact with itself. That’s why we want to strongly enforce all the best practices around public methods, while we can take it more easily on private/protected methods.
Now, even if we assume that every object in our system only allows any other object to interact with him through behavior-driven methods, this is not enough: we need to take care of the scope and the visibility of every interaction over the communication chain to ensure that coupling is the lowest possible.
If we don’t do this, we might find ourselves with a system where every object accesses the internal collaborators of every other object, leading to a messy system where communications and collaborations are not clear and straightforward.
In this kind of system, we repeatedly fall into the code smell of the Message Chain; this is an example of this code smell:
$dog->body->tail->wag();
We have an instance of the Dog
the class that exposes a property body
returning a class that exposes a property tail
returning a class that exposes a method wag
.
We exposed all the implementation details of our Dog
class. Terrible.
Imagine this example as the standard way of implementing things all over the system - it’s a mess, a big one. We are leaking implementation details in our object, giving access to the internal collaborators of a class to the outside and therefore allowing the external to access the collaborator through our object.
This is bad, very bad - the same bad as giving access to the internal data, and similar are also problems: this will immediately cause the caller to interact with the collaborators of our class outside of it and implement a behavior that should have been encapsulated in our object instead.
How can we avoid all this?
We can use the Law of Demeter, which states as follows:
Each unit should only talk to its direct collaborators.
Aka “don’t talk with strangers” and “Principle of Least Knowledge”, this law wants us always to keep the lowest coupling possible between objects, and enforce encapsulation to hide implementation details and ensure that the only thing that objects know of each other are the public methods and their signature.
Fixing the previous example, the Dog
class can simply expose a method expressHappiness
:
$dog->expressHappiness();
We don’t need to know how the Dog
class implements the dog body structure, and we don’t have to know that expressing happiness means wagging the tail - we just ask the Dog
class to execute the behavior it is exposing. and we trust that it will handle it, eventually returning the resulting data he promised me
To achieve encapsulation properly, we need to ensure that the caller of our message does not know anything about the implementation of the behavior - he just doesn’t care, we only need to ensure that the behavior we promise is implemented and data needed is returned, that’s it. If we leak implementation details, it’s a problem because callers will start to count on that, and this coupling will reduce our freedom with future changes.
🧠 Test Yourself in 1 minute:
💡 Did you know? An interactive activity, like quizzes or flashcards, can boost your learning!
Take advantage of our set of Flashcards dedicated to this topic: read the word and try to describe its definition - then turn the card to check the correct one for feedback 😲 Don't miss out on the opportunity to boost your learning—try now!
Object-Oriented Programming definition
Insights Recap
Object Oriented Programming definition:
A system made of objects that communicate with each other through messages.
With messages, we refer to the public methods
Having behavior-driven methods as the only way to communicate between objects is great but not enough: those methods needs to hide all the implementation details
We want to absolutely avoid the Message Chain code smell
To avoid this we can use the Law of Demeter: “each unit should only talk to its direct collaborators”.
Other names for the Law of Demeter are:
don’t talk with strangers
Principle of Least Knowledge
To achieve encapsulation properly, we need to ensure that the caller of our message does not know anything about the implementation of the behavior
Until next time, happy coding! 🤓👩💻👨💻
Go Deeper 🔎
Legenda
📚 Books
📩 Newsletter issues
📄 Blog posts
🎙️ Podcast episodes
🖥️ Videos
👤 Relevant people to follow
🌐 Any other content