Have you heard of The Law of Demeter? I haven’t until recently I’ve come across this term a few times in one day. Immediately I decided to take more closer look and get familiar myself with that term. It turned out that it’s not about ancient mythology… well… it’s named in honor of Demeter which is in Greek mythology:
is the goddess of grain and fertility, the pure nourisher of the youth and the green earth, the health-giving cycle of life and death, and preserver of marriage and the sacred law.
But our Law of Demeter is about software engineering, to be more precise it is about a design guideline for developing software also called as “Only talk to your immediate friends”.
First a came across this term reading Martin Fowler’s article “Mocks Aren’t Stubs” which is really great article where he explains differences of Test Doubles. If you don’t really know the difference between Dummy, Fake, Stub and Mock objects, go and read it, the article is great source of that knowledge. BTW, I think I’m a classic TDDer who uses Mocks for the real objects that are awkward to work with.
So, back to LoD in “Mocks Aren’t Stubs” Martin Fowler talks how your testing style influence the design style.
Mockist testers do talk more about avoiding ‘train wrecks’ – method chains of style of getThis().getThat().getTheOther(). Avoiding method chains is also known as following the Law of Demeter. While method chains are a smell, the opposite problem of middle men objects bloated with forwarding methods is also a smell.
And there is a good article on Google Testing Blog describing why violation of LoD is a smell and how to avoid it.
To me it’s not only about number of dots in a “train wreck” it’s about behavior of objects and their responsibility.
The most famous example showing LoD violation is Paper boy.
The first point is that the customer usually does not give the wallet to the paper boy to pay for the paper bill. Instead, the customer takes out the money from the wallet and hands it to the paper boy.
Instead of using (in class PaperBoy)customer.wallet.totalMoney;
we use a method:customer.getPayment(..)
You don’t want to give away your wallet that’s true, but sometimes two dots don’t necessarily mean that there is a LoD violation.
Let’s take an example getOrder().getCustomer().getCustomerAddress(). Do we want to delegate the getCustomerAddress() instead?
The question is should the order have a getCustomerAddress() method?
That’s what a few experts think about LoD:
The basic effect of applying this Law is the creation of loosely coupled classes, whose implementation secrets are encapsulated. Such classes are fairly unencumbered, meaning that to understand the meaning of one class, you need not understand the details of many other classes.
— G. Booch.
Avoid traversing multiple links or methods. A method should have limited knowledge of an object model. A method must be able to traverse links to obtain its neighbors and must be able to call operations on them, but it should not traverse a second link from the neighbor to a third class.
— J. Rambaugh
There are so many resources out there about this subject, if you’re interested I would suggest to read: