Style question: Nicknames for deeply nested objects

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Jan 30 17:02:03 EST 2011


On Sun, 30 Jan 2011 12:51:20 -0500, Gerald Britton wrote:

> Hi all,
> 
> Today I was thinking about a problem I often encounter.  Say that I have
> (seems I often do!) a deeply nested object, by which I mean object
> within object with object, etc.
> 
> For example:
> 
>    x =
>    some.deeply.nested.object.method
(some.other.deeply.nested.object.value)
> 
> Well, that's extreme but I've worked with code approaching that level of
> nested-ness.

Then you're probably living in a state of sin, programming-wise, and you 
should stop doing that! You are violating the Law of Demeter. One dot, 
good. Two, acceptable. Three is a code smell. Four is a code reek.

The Law of Demeter (more of a guideline than a law, really) says:

If you want to get your dog to walk, call the dog. Don't talk to its 
legs, it confuses the dog and doesn't get it anywhere.

http://en.wikipedia.org/wiki/Law_of_Demeter

Another analogy: if you have to pay the paperboy for delivering the 
newspaper, you don't let him reach into your pocket, take out your 
wallet, open the wallet, take out whatever money he feels like, and put 
the wallet back.

http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-
boy/demeter.pdf


Despite my comment above, the Law of Demeter is not *really* a dot-
counting exercise, although that's a handy short-cut for detecting 
potential problems. It can also apply to other data structures. If you've 
every seen C or Pascal code where you have a pointer to a pointer to a 
pointer to a pointer to a pointer to a pointer to some data, you've seen 
a violation.

Consider your example:

some.other.deeply.nested.object.value

This is very tightly coupled code: the caller, who knows about the object 
`some`, needs to know the internal details of not just `some` but also 
`other`, `deeply`, `nested`, and `object`. As a basic principle, this is 
poor design! Which would you rather deal with?

car.start()

car.ignition.turn(key).connect(car.starter(battery), car.spark_plug)

In particular, using temporary variables merely disguises the problem:

temp = some.other
temp = temp.deeply.nested
x = temp.object.value

Even though you never use more than two dots, you still have tight 
coupling. The point of Demeter is not to save dots (they're a renewable 
resource) but to reduce tight coupling.


-- 
Steven



More information about the Python-list mailing list