Object-oriented programming might be a very strong & powerful way of writing code for software development, but many errors may arise when used improperly. OOP can provide you with a variety of features that can let you handle a lot of common programming issues, but when you exploit the usage of these features, you might end up developing spaghetti code.
So, you might wonder what spaghetti code looks like. Is it yellow and stringy? Well, spaghetti code is a term used in programming to denote that your code is tangled in itself where the source code accesses everything it needs randomly from anywhere without following a certain protocol or style – and therefore resembles a plate of spaghetti. Code like this can be hard to maintain & visualize for long-term purposes.
Loose Coupling and Tight Coupling
So, what exactly is the Law of Demeter? The Law of Demeter is a principle or a guideline that is used in object-oriented software development, which is based on the idea of Loose Coupling.
Loose Coupling is a design concept that encourages the reduction of one class's dependencies on another and ensures that those classes don't break due to changes in each other. On the other hand, Tight Coupling means that the components or objects are heavily dependent upon other classes' components and objects.
The Law of Demeter
The Law of Demeter is also known as the dots rule/multiple dots rule. Demeter Law is therefore based upon the idea of Loose Coupling, which can be summarized in the following ways:
- Each unit should have limited knowledge about other units: only units "closely" related to the current unit.
- Each unit should only talk to its friends; don't talk to strangers.
- Only talk to your immediate friends.
This law creates minimal privileges for classes to contact or make changes to each other. It lets a single module only access the information and resources that are strictly necessary for the module's functionality.
Here's an example code that violates the Law of Demeter:
Let's diagnose the code above.
We can see we first get access to our player class and then get the nearest object from it. However, when we try to get the stats component of the nearest target, we don't know what type of class we are going to get from the
GetNearestObject. This is the first bad dependency we get. Similarly, when we try to update the UI, it creates another dependency.
The problem with the code is that the code chain has too many link dependencies, and if we proceed to do a single change to the part of the chain, everything needs to change according to their dependencies. This is not a suitable way to implement such a functionality.
So, to solve the problem with the above code, you will have to write something like:
This way, you will have a loosely coupled code where the player class will contain more code, but the chain link will be eliminated, making the code much safer. All the checks for objects with Stats can be checked inside the player class. Also, any changes to StatsComponent will be easier to find now.
Here's another use case for the Law of Demeter:
The above code is another example of a violation of the Law of Demeter.
PlayerUI class, the
if statement checks through a chain of links just to find the
maxPowerLimit of a powerup. Let's take an instance here: if there are some changes to the
PlayerPower class that lets it hold more powerups, we will have to create more dependency chains for
PlayerUI, which will make the code harder to manage and retain editability.
To fix the above code according to the Law of Demeter, we can:
Here, we now make sure that our
PlayerUI class gets limited information from the
PlayerPower class. We have also decoupled the chain by passing in our
PlayerPower object as a parameter for the UI update, and we have added a line of code in the
PlayerPower class that lets us get the read-only
maxPowerLimit through a function.
I have also separated the
TeleportPowerUp by making it inherit another parent class called
PowerUp that makes sure that the
PlayerPower class only handles the current powerup – making the code reusable for every other powerup as well.
The Law of Demeter reduces long dependencies among classes and their objects, ensuring the code isn't spaghetti. You can also use actions, delegates, and properties to solve these huge code dependencies. Following the Law of Demeter also lets you create more robust and reusable code as most of your code becomes more suitable for later use because of its independence.
Thank you for reading and learning with me. Please leave comments if you have any regarding this article.