Introduction
If you have been using an OO language to program with then you should have heard of the Law of Demeter. If you haven’t then you should read some of the articles I collected on Google.
- Wikipedia
- The Paperboy, The Wallet, and The Law Of Demeter by David Bock
- Introducing Demeter and its Laws
- Entities and the Law of Demeter by Jimmy Bogard
Definition
It is actually very simple to me. But explaining it can be a bit more daunting. This is what you can find on Wikipedia about it.
**When applied to object-oriented programs, the Law of Demeter can be more precisely called the “Law of Demeter for Functions/Methods” (LoD-F). In this case, an object, A, can request a service (call a method) of an object instance, B, but object A cannot “reach through” object B to access yet another object, C, to request its services. Doing so would mean that object A implicitly requires greater knowledge of object B’s internal structure. Instead, B’s class should be modified, if necessary, so that object A can simply make the request directly of object B, and then let object B propagate the request to any relevant subcomponents. Or A should have a direct reference to object C and make the call directly. If the law is followed, only object B knows its own internal structure.
More formally, the Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:
O itself
M’s parameters
Any objects created/instantiated within M
O’s direct component objects
In particular, an object should avoid invoking methods of a member object returned by another method. For many modern object oriented languages that use a dot as field identifier, the law can be stated simply as “use only one dot”. That is, the code “a.b.Method()” breaks the law where “a.Method()” does not. There is disagreement as to the sufficiency of this approach.
My side of the story
Let’s oversimplify this a bit. When you see 2 dots in a statement, then you know something is going to be wrong. Look at this:
vbnet
Dim _Person as Person = New Person
Console.WriteLine(_Person.Addresses.Count)
In that example _Person.Addresses.Count is a smell. Why? Because Addresses could be null and when it is null it can give a nullreferenceexception and crash our program.
There are 2 ways around this problem.
First.
vbnet
Dim _Person as Person = New Person
Try
Console.WriteLine(_Person.Addresses.Count)
Catch ex as NullReferenceExceptionException
Console.WriteLine(0)
End Try
or
vbnet
Dim _Person as Person = New Person
If _Person.Addresses IsNot Nothing then
Console.WriteLine(_Person.Addresses.Count)
Else
Console.WriteLine(0)
End If
What is wrong with this approach? Well every time you call Addresses.Count you have to check if Addresses isn’t null and print 0 instead. This gets boring very quickly and sometimes somebody might forget this little detail.
So we have a better solution. Namely, add a Method/Property to our Class Person. We name it CountAddresses for example and it would look something like this.
vbnet
Public Function CountAddresses() as Integer
If _Addresses IsNot Nothing Then
Return _Addresses.Count
Else
Return 0
End If
End Function
Now we can call CountAdresses instead of Addresses.Count and not have to fear NullReferenceExceptions anymore.
The downside of this is that you have to write more code in your classes. But less code in your calling classes.
So I guess you should use it wisely.
When not
And when doesn’t the Law of Demeter apply?
- Fluent interfaces (Unlimited amount of dots)
- Factory classes (You can have 2 dots there)
- Legacy systems (No laws apply in there)