Less APIs or more encapsulation?

Diez B. Roggisch deets at nospam.web.de
Wed Sep 9 17:25:12 CEST 2009


一首诗 wrote:

> 2 class,  B contains C.   When user want to use some service of C,
> there are two choice:
> 
> First, more encapsulation:
> 
> =============================
> class B:
>     def newMethod(self):
>         self.c.newMethod()
> 
> class C:
>     def newMethod(self):
> 
>       #do something
>         pass
> 
> b.newMethod()
> 
> 
> ==============================
> 
> Sencond : Call seice of f c directly:
> 
> 
> =============================
> 
> class B:
>     pass
> 
> class C:
>     def newMethod(self):
>         # somethining
>         pass
> 
> b.c.newMethod()
> 
> =============================
> 
> 
> Generally, what I learned from books told me that 1st choice is
> better.
> 
> But when C has many many methods to expose to outer user, 2nd choice
> seems to be more reasonable I In the first design, B.newMethod did
> nothing really useful.
> 
> ctaully, , there are D/E/F, etc. in B we methodhod has to be exposed
> to user code,  which makes encapsulation more tedious.
> 
> 
> In fact, these classes,  C/D/E/F all have different jobs, but they all
> belongs to a real world object "B", B is only a container of C/D/E/F.
> 
> What do you think about it?

This is a problem the Law of Demeter is concerned with:

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

Generally speaking, you should favor solution a over b. If you really have
so many instances that expose their services through a container, you might
consider creating code that makes declaration of pure delegates easier.

Or maybe even redesign your code - if it would be ok for other code to work
like this:

  work_with_c(b.c)

without intermittently referring to b, I think it's ok. If not, you should
delegate, because then functionality obviously depends on some new
behavior.

Diez





More information about the Python-list mailing list