You’ll often get to hear from good programmers about having “loosely coupled” classes.
What do they mean by saying that?
Let’s understand this first before jumping onto the Law of Demeter.
In object-oriented design, the amount of coupling refers to how much the design of one class depends on the design of another class. In other words, how often do changes in class A force related changes in class B? Tight coupling means the two classes often change together, loose coupling means they are mostly independent. In general, loose coupling is recommended because it’s easier to test and maintain.
Let’s move back to the Law.
The Law of Demeter
In layman’s terms, this law says what we are told since our childhood – “Don’t talk to Strangers”.
Talking in technical terms,
It says our function should only access the classes/objects that it has direct access to which are:
i. Objects in class parameter
ii. The object in function parameter
iii. The object in class members
iv. Objects created inside the function body.
A can talk to B since A is a friend of B. So, A can send and receive messages from B. By messages, we mean accessing its objects. But C is a stranger to A. So, any conversation between A and C is a clear violation of this law.
In short, the Law of Demeter aims to keep you from doing things like this:
or even worse, this:
The intent of this “law” is to prevent you from reaching into an object to gain access to a third object’s methods.
Let’s understand the Law of Demeter with an example:
Translation class looks like:
As you can see that the Translation class has a class parameter “dictionary” of type Dictionary. In the wrongUsage() method through the translation object we are calling the translate method of the dictionary object which is foreign to our wrongUsage() method.
Clearly, this shouldn’t happen.
Before going onto how it should’ve been done, let’s see why LoD restricts us from doing this blunder.
Till now we have seen that this translate object is from some third party library (which we are using) is further using some other library Dictionary. So, this Dictionary class is foreign to us. Right?
No surprise that this library might change its method in further releases.
Say, for example, it changes the method parameter. Earlier it used to take a String parameter (see the above snippet) and now it takes some TranslationString object.
So, in this case, will our code still be working fine?
The answer is obvious, a big NO!
Though Translation class has handled the changes:
and since we are trying to be friendly with the foreign library, so this impacts our code:
Time to see what should be the best way to do this?
Things make sense now! We have to just call the translate method of Translation class, how translation will deal with the foreign library we shouldn’t be concern about that.
If you’re still not clear with this, you can check its complete implementation from here or you can ask in the comments.
You can further read about Clean Code from this blog.
Hope it helped! 🙂