Law of Demeter
Introduction
The Law of Demeter (aka Principle of Least Knowledge) is a nice little trick you can use when writing programs according to the principles of OOP.
What is it?
The law is simply this. In any piece of code, the code can only refer to:
- Methods of self / this
- Attributes of self / this
- Methods of attributes of self / this. (This is the only case of using two 'dot's.)
- Parameters to the method.
- Methods of those parameters.
- Stuff created as part of the method.
- Methods of stuff created.
Or, in simplest terms:
GOOD:
self.X self.X() self.X.Y() X X.Y()
BAD:
self.X.Y self.X.Y().Z X.Y X.Y().Z Z = X.Y(); Z()
Examples
The following code is OK: (Python code below)
def foo(self, bar): self.foo() self.a self.a.foo() bar.foo() baz = Baz() baz.foo()
While the following code is not OK:
def foo(self, bar): self.foo().bar() self.foo().attr self.a.foo().attr self.a.foo().foo() bar.attr bar.foo().foo() bar.foo().attr baz = Baz() # this is actually OK baz.attr baz.foo().attr baz.foo().foo()
Why?
Why should you follow the Law of Demeter? Because it helps you write easier code.
Think of it this way. Any bit of code has to "know" all about its parameters and the object it is a method of. By "know", I mean that certain assumptions are made about what the object is and what attributes and methods it has.
By using the Law of Demeter, the "knowledge" of the code is dramatically reduced. This is because the code is written assuming that the object, the parameters, and the created objects are understood. And even then, only the methods of the parameters and created objects are assumed.
My Adaption
Now, I am a firm believer in Attribute-Method Equivalence.That is, simply, that there should be no difference between attributes and methods except that methods are attributes that are callable. So the way I look at the Law of Demeter is to count the number of dots and that's it.
This works extraordinarily well in languages like Python and Javascript, where the idea of writing a template that describes what attributes and methods an object will have is absurd. This doesn't work so well for languages like Java and C++ and even Perl where you spend all your time writing these templates. For these languages, the traditional Law of Demeter is wisely followed.