How does the Law of Demeter applied to object-oriented systems with coupling and cohesion?
I was reading a book “Software development and professional practice” and came across the chapter about LoD, and was curious about how that principle is applied into object oriented systems.
1
According to Emerson Macedo the Law of Demeter states the following:
- Each unit should have only 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 corresponds directly to the principle of low coupling as the units (or objects) are supposed to, much like above:
- Not be tightly coupled to each other. Only the closest ones are.
- Each one should only talk to its collaborators and not to the collaborators of the collaborator
- Only talk to immediate collaborating object
One of the lowest forms of coupling is message passing, i.e. the data is shared between objects through method calls with parameters.
Furthermore, from what I can see, the Law of Demeter does not directly correspond to the principle of high cohesion as that only states the objects themselves should know what data they possess themselves. An object with low cohesion has data members that it is not using frequently in its own methods. It is more about the contents of an object rather than its relationships and collaborating objects.
Coupling, simplified
When an object calls a method, property, etc. of another object we say the objects are coupled. We call it coupling because now the callee cannot change anything about its own method/prop. w.out breaking the caller.
Thus, the more the coupling – methods, props. – the harder it is to change callee code without breaking all the code that uses it.
contemplating coupling
- Referencing even a single prop., method couples two objects.
- Obviously coupling is necessary for creating software.
- Given the ‘lock step’ nature of coupling we want to both limit and isolate it. This goal simply goes along with general software dev. principles.
- The fewer objects we have to talk to, the lower the coupling.
- If I need to make, say, 20 different method calls the coupling is lower if all 20 calls are to one class/object, vice those same methods spread over several classes/objects.
Most Knowledge causes crazy coupling
Here we have an Employee
that has a Person
that has a ‘Address’
public class Employee {
public Person me = new Person();
}
public class Person {
public Address home = new Address();
}
public class Address {
public string street;
}
To get the street I must call: myEmployee.me.home.street
. This is 180 degree opposite of the principle of least knowledge. I have to know about the internals, the composite structure, of the Employee
, Person
, and Address
classes.
This defective class design forces me to know about all those classes and thus myEmployee.me.home.street
couples me (the caller object) to no less than 3 classes – to get only a single property!
Least Knowledge Saves the Day
If I talk to only the Employee
class I am applying the least knowledge principle per se, and by doing so we automatically limit coupling to only that class, and at the same time isolate coupling to that one class.
By adding all the needed properties in the Employee
class we fix the coupling.
thus
public class Employee {
public Person me = new Person();
public string street { return me.home.street; }
}
Allows me to call: myEmployee.street
–
- I “know” only
Employee
- I am coupled to only
Employee
– no matter how complex its structure.
Least Knowledge all the way down
We decoupled myEmployee from Person
and Address
, and ideally we should continue applying least knowledge by adding pass through properties such that Employee
only talks to Person
and Person
only talks to Address
Study (V. Basili, L. Briand, and W. L. Melo. A validation of object-oriented design metrics as quality indicators) has shown that classes with larger response sets have tendencies to create more errors than classes with smaller response set because more response set means the chance of higher coupling.
The value of Law of Demeter is that it reduces response set by definition. An object’s method can only call a method of itself, any parameter that were passed onto the method, method of any object it created, and method of any directly held object. Since the response set is smaller, there is less chance of high coupling. Since the module/method is only using immediate available references there is higher cohesion.
1
It is pretty simple; say A depends on B and B depends on C.
Without the Law of Demeter you can use both B and C in A but by adhering to this law, A depends only on B, it cannot depend on C.
This enables low coupling since it greatly reduces the number of dependencies of a module; cohesion, although different in concept from coupling, is achieved in the same way. By having fewer dependencies on a module, these become more specific for that module and thus increase cohesion. Also the total number of modules will rise and they will become more specialized for doing stuff specialized for the depending module (contrary to god objects) which directly translates to more coherent system.