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