I was watching a Google Tech Talk on Dependency Injection. Sixteen minutes in the speaker gave an interesting example of the Law of Demeter: If buying item for $25 in store, do you hand clerk $25 or give clerk your wallet and have him/her retrieve the $25.
This got me thinking about why we so frequently violate the Law of Demeter. I can think of three reasons that come up frequently.
Familiarity with code/process
When we think about what needs to be done, we think “I’ll get out my wallet and get the money.” This does translate literally to handing the clerk the $25. Since the wallet is an inanimate object, we think more about the wallet than the cash.
Wallet wallet = customer.getWallet();
Cash cash = wallet.getMoney(25);
If it were a person, we would think of the separate step. If a six year old was buying something, he might think of the transaction as “ask mommy or daddy for $25 and then hand that to the clerk $25.” This translates better to:
Cash cash = parent.getMoney(25);
In the real life scenario of an intermediary person, the requestor (child) never even rifles through the wallet. (Granted in the real life scenario, the child doesn’t really ask the wallet – rather the person holding the wallet.)
Access data we shouldn’t
This is really a variant of being overly familiar with all the objects/data. We tend to think about what we are doing rather than from the object’s point of view.
Can’t touch other code
To me this is the most interesting reason. We have an object that we think really should have a new method but can’t touch that object. One solution to this is to create a new object that holds the original and does contain the new method. This solution is useful when the object belongs to a third party and really can’t be changed. Sometimes it’s more of a mental block.
I recently came across a case where two numbers where compared via a string comparison (and some other logic) because the author didn’t want to touch the object that owned the data (and was exposing it via a string.) After further discussion we concluded the owning object really needed a method that told us if this number was positive or negative. And the complex logic was a “code smell” pointing us to that fact.
Personally, I find the reasons behind things to be more interesting than the actual instance. It’s easy to say “don’t violate the Law of Demeter.” Discussing why is plenty interesting (as in the Google Tech Talk.) It’s thinking about what drives us to such things that helps actually prevent them.