LoD questions

Roeland Rengelink r.b.rigilink at chello.nl
Wed Sep 19 04:58:27 EDT 2001


Paul Winkler wrote:
> 
> 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")
> 

Note that you've really only replaced dots with underscores here. The
structural knowledge is still there. If you end up with hundreds of
methods like this in foo, you know something is wrong.

I think that LoD is saying that if x needs a baf and if foo is the only
reasonable place to get it, then foo should have a method get_baf()

x = foo.get_baf()

foo can of course implement this as:

def get_baf(self):
    return self.bar.get_baf()

and bar can do

def get_baf(self):
    return self.bat.get_baf()

etc. etc.

However, if foo ends up with:

def get_bars_baf(self):
    return self.bar.get_baf()

def get_oomps_baf(self)
    return self.oomp.get_baf()

You may already be in trouble. x just wants a baf. If it has to tell foo
where to get it, foo is not the place to get it from. (or baf may not be
the proper thing to ask from foo, or x is in the wrong place, or baf is
in the wrong place, or oomps baf is not really a baf, or...)

> 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")
> 

I think you shouldn't think of LoD as a rule that tells you how many
dots (or underscores!) you can use in indirection, but as a hint that
tells you that if you need many dots then there may be something wrong
with your code. In general you're in bigger trouble if you need three
than if you need two.

It is difficult to say what may be wrong without knowing more about your
code. 

Just one hint, beware of the FORTRAN common block. If foo's only
function is to pass
bar and oops around, then just pass bar and oops around, and get rid of
foo.

Hope this helps,

Roeland
-- 
r.b.rigilink at chello.nl

"Half of what I say is nonsense. Unfortunately I don't know which half"



More information about the Python-list mailing list