Dependency Inversion Principle -- Python Way

Ype Kingma ykingma at accessforall.nl
Mon May 21 22:10:46 CEST 2001


Sasa Zivkov wrote:
> 
> Hi,
> 
> I have read some discussions on this mailing list about DIP (dependency
> inversion principle) and theoretically everything is clear to me.
> 
> So if we have two classes A and B such that A->B (a depends on B)
> and B->A then we have cyclic dependency.
> One way to break this cycle is to use DIP.
> According to DIP we define an abstract interface C such that:
> B uses C
> A implements C
> 
> and we finish with acyclic dependencies: A->B, B->C, A->C.
> 
> Now, I want to ask you about implementation.
> 
> 1. Would you really declare class ("interface") C in python ?

No.

> 2. Because python has only implicit interfaces is not is enough just to
>    implement C interface in A ?

Yes.

> 3. Finally if I decide not to really make C class but only
>    to implement this interface in A I will finish with almost the same
>    situation as at the beggining: two classes A and B where A->B and B->(C
> part of A)
>    I am a little confused at this point :-)  ... it seems like I did really
> nothing.

Precisely.

> 
> Your thoughts ?

In a strongly typed language you have this problem and you'll find the
A->B, B->C, A->C dependencies back in the import/include/use structure
needed to get your modules compiled.

In Python the equivalent checks are done at runtime, so there is no
need to predeclare C.
Still, I prefer to document the C interface in somewhere my python code
so it can be easily reused.

Note that you can even delay the implementation of interface C in class A
until you actually need it. Eg.

class B:
    def __init__(self, glasses):
        self.glasses = glasses

    def lookatThing(self, thing):
        thing.inspect(self.glasses) # thing conforms to C, it should have inspect().

class A:
    def __init__(self):
        self.theB = B('goggles')

    def receiveVisitor(self, whichAudit):
        if whichAudit == 1:
            self.inspect = self.audit1 # dynamically adapt self to have inspect() method.
        else:
            self.inspect = self.audit2
        self.theB.lookatThing(self)
        del self.inspect

    def audit1(self):
        print 'audited1'

    def audit2(self):
        print 'audited2'


Fortunately you only have to try imagine how you would do this in a typed language.

Have fun,
Ype
-- 
email at xs4all.nl



More information about the Python-list mailing list