LoD questions

Ype Kingma ykingma at accessforall.nl
Tue Sep 18 16:42:46 EDT 2001


Paul,

> 
> I've been reading about the Law of Demeter which says, in a nutshell,
> that methods should only talk to their "close friends", a concept
> which seems to be vague by intent.
> 
> My question boils down to this: How does one find an appropriate
> balance between minimizing the number of dots and managing the number
> of methods in the parent object?
> 
> If I have an object, foo, that contains lots of information, the LoD
> says that however I organize it, I don't want to directly dig deep
> inside like so:
> 
> x = foo.bar.bat.baz.baf()
> 
> But it may not be practically possible to put methods for every
> possible thing directly in foo, or else I'll have hundreds of methods
> that look like
> 
> x = foo.get_bar_bat_baz("baf")
> 
> So what's a reasonable compromise? Is it generally considered OK under
> the LoD to reach directly in two layers? e.g.
> 
> x = foo.bar.get_bat_baz("baf")
> 
> So we only need to know about foo that it contains an object bar with
> a method a get_bat_baz("baf") and don't need to worry how that method
> works.
> 

It depends :).
When you find yourself writing foo.bar.bat a lot of times in the
methods of the class of foo, it 
is reasonable to consider foo.bar.bat a "close friend" of foo,
so you introduce:
    foo.bat = foo.bar.bat
at an appropriate place, possibly in the __init__() method.
This is more concise, and more efficient.
It also reduces the need for get_bar_bat_baz() methods considerably.

This is related to some OO design issues:
- method normalisation, ie. introduce methods only for independent
  functionalities, except when performance requires otherwise
  (foo.bar.get_bat_baz() might be foo.bar.getbat().getbaz()), and
- when there are many different objects involved in a series of steps,
  which object should call which?. There are two extremes: one object
  calls all the other ones, and: each object only calls one other object.

Given these choices, you choose the ones for which you expect the future 
maintenance to be confined to as few classes as possible:
When you expect the order of steps to change, choose a central object.
When some of the steps are not related at all to a central object,
move them into a method of an object/class to which they do relate.

If that sounds rather abstract, try thinking in responsibilities:
which object/class should be responsible for which (kinds of) steps?

Have fun,
Ype

-- 
email at xs4all.nl



More information about the Python-list mailing list