The Law of Demeter is a Piffle

May 8, 2008 Pivotal Labs

One of The Blabs’ most controversial articles was Lovely Demeter, Meter Maid, in which Pivotal and Thoughtworks battle over which Agile consultancy has the better understanding of the Law of Demeter, and which has better hair and music taste (seriously).

I have never found this “law” very persuasive.

  • The bizarre, culturally loaded analogy about a paperboy and a wallet says nothing insightful about encapsulation boundaries as they arise in real software systems.
  • The blogosphere’s endless scholastic hermeneutics of the law’s 4 allowances for message sending is a masturbatory philosophical enterprise with nothing relevant to real-world software.
  • The Mockist’s insistence on easy mockability is of dubious merit–build better mocking frameworks!
  • And the few practical, real merits that arise in from following the Law of Demeter are better arrived at using other techniques, such as “Tell, Don’t Ask”.

Here Are Two Examples, one where I violate the Law of Demeter, and another where I don’t.

I wrote this code recently, in flagrant violation of the Law:

cookies[:store_id] = @login.store.id

Suppose @login is not an ActiveRecord object, it does not automatically have a #store_id method. Should I create a delegator for this?

class Login

  def store_id

    store.id

  end

end

This is pretty silly. The store_id is not an attribute of the login; rather it’s an attribute of the store, and the store is an attribute of the login. The delegator is needless code cruft to replace a dot with an underscore, it smells of the endless boilerplate Java code of my youth. Demeter be damned.

On the other hand, here is a refactoring I did, incidentally complying with the law of Demeter:

Here is the original, Demeter-violating code:

def find_attribute_given_name(name)

  attributes.detect { |a| a.name_or_alias == name }

end

The call to == here is the violation of Demeter. I later replaced this with:

attributes.detect { |a| a.named?(name) }

The latter complies with the “law”. And it’s much better code. But was I lead to the improvement to this by Demeter? No, I was lead to it by a better understanding of the encapsulation boundaries of the object (#name_or_alias became private) and by a desire to have my code be more terse and clear. a.named?(name) is the most terse explanation of the intended computation that I can think of.

Demeter be damned.

About the Author

Biography

Previous
Better Javascript testing through ScrewUnit
Better Javascript testing through ScrewUnit

The following is an excerpt of ScrewUnit's new copious documentation: Writing Good Tests A great test max...

Next
Screw.Unit 0.3
Screw.Unit 0.3

Screw.Unit 0.3 is now available. I'm skipping 0.2 since there have been two milestones worth of additions t...