This law says exactly what we have been told since our childhood - Don’t talk to Strangers.
I’ve often heard about having “loosely coupled” classes and functions. The following definition is taken from GeeksForGeeks.
“Loose coupling means the classes are mostly independent. If the only knowledge that class A has about class B, is what class B has exposed through its interface, then class A and class B are said to be loosely coupled.”
Going by definition, suppose we have two classes, A and B. If class A allows class B to make changes in class A, and class A knows about class B only as much as it is exposed through the interface of B, the classes are loosely coupled.
Why Do We Need Loose Coupling?
Suppose I have written a piece of code that consists of two classes, A and B. Now, I would want the design of my classes to be in such a way that if I wish to make any changes in one of the classes, it should have minimal impact on the second class. In other words, how often do the changes in class A make changes to class B? Tight coupling means the two classes will often change together, loose coupling means they are mostly independent. If my classes are loosely coupled, it will be easier to test and maintain my code in the future.
What Does It Mean in Technical Terms?
It says our function should only access the classes/objects that the function has direct access to, which means it should only access:
Objects in class parameter
Objects in function parameter
Objects in class members
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.
How to Apply Law of Demeter?
I have applied the Law of Demeter to a java program for a scenario with a Customer. A paperboy will collect the money from the customer’s wallet, as the customer has given the paperboy the direct access to his wallet.
The Original Customer Class
Why is This Bad?
The 'paperboy' class now knows that the customer has a wallet, and can manipulate it. When we compile the paperboy class, it will need the customer class and the wallet class. These three classes are now 'tightly coupled'. If we change the wallet class, we may need to make changes to both of the other classes.
If our future wallet object holds credit cards, the paperboy has access to those too, but the basic problem is that the paperboy is being exposed to more information than he needs to be.
Applying the Law of Demeter in the Original Code
When to Apply Law of Demeter?
The Law of Demeter is one of the most well-defined, useful, and concisely written rules of Object-Oriented software development. It is one of the most ignored topics in our profession. While reading some articles, I found that there are some opinions expressing that the Law of Demeter is less of a “law” and only a “suggestion” or a “guideline.” However, the Law of Demeter is the law of the land in Object-Oriented development. It is the Law of Good Style and must be followed in all object oriented programs.
Why Is This Better?
The code gets maintainable and flexible. It becomes adaptable to changes with minimal concerns for the programmers.
Direct access to private data members can be avoided to a third party by forming chain calls. There is a reduced risk of unrevised methods going unnoticed somewhere else in the code.
Also, if objects are too tightly coupled and the order in which the methods receive arguments is altered, the arguments must be switched everywhere else, thus, the method is called within the code.
What are the Drawbacks of the Law of Demeter ?
It may result in having to write many wrapper methods to propagate calls to components; in some cases, this can add noticeable time and space overhead.
If the Law of Demeter is not used correctly, wide (i.e. enlarged) interfaces may be developed that would require introducing many auxiliary methods.
Suppose we have to write logic to figure out taxes based on the country code of a person. The basic logic is:
Suppose Person class is defined as having an address, i.e., class Address. Class Address has access to class Country. Country has a code attribute that returns a string(zipcode). These aren’t objects to which we are sending messages, but these are data structures that are navigating to access data from our domain model, where all of the methods are just attributes returning unfettered access to public members of a data structure.
For classes that are really just data structures, like the one explained above, when they are core domain concepts, applying the Law of Demeter does more harm than good.
The Law of Demeter is all about hiding implementation as much as possible to outside code so one won't have to refer to different parts of the code to get something done.
We should only create classes that communicate with closely related classes, rather than talking with all sorts of classes.
Talking with all kinds of classes creates a mess of references that’s hard to figure out when we need to change the code.
Thus, maintainability, flexibility, and testing of code gets easier with the Law of Demeter.