[Zope3-dev] Zope 3 Source organization

Phillip J. Eby pje@telecommunity.com
Mon, 14 Jul 2003 13:37:04 -0400


At 06:25 PM 7/14/03 +0200, Martijn Faassen wrote:

>We need to offer a development model that supports this mode of
>development -- tightly coupled code. Zope 3 is very good at decoupling
>code, but it's not good at supporting tightly coupled code. We consider
>this code inflexible and bad, but it's the code that gets a lot of
>the world's software going. In XP it'd also be often the code you start
>out with, doing the simplest thing you can possibly do.

This is a nice succinct explanation of why I gave up on the idea of 
developing applications using zope.app, and am working on an "ultra light" 
alternative for more tightly-coupled applications that are written by 
Python developers rather than content managers.  I don't think that 
zope.app supports that model well at all -- too many separate and loosely 
coupled things to configure to get anything done.  (But that's not to say 
that I think zope.app should change; I'm sure Zope Corporation is taking 
the direction they believe will be most useful for their business, as they 
should.)

Interestingly, I've found that being "closely coupled" isn't the same as 
"tightly coupled".  If you can link things one way, then as long as you can 
redefine that linkage in another context, it's okay to have the 
coupling.  Such an approach is far more concrete and tangible to work with, 
yet still be reused.  E.g.:


class Contact(Persistent):
     # blah


class ContactView(blah):
     protocols.advise(
         instancesProvide = [ISomeKindOfView],
         asAdapterForTypes = [Contact]
     )

     # blah....


Now, although this is "closely coupled" in that code is registering an 
adapter for code, the Contact class could still be coupled to a different 
view in another context:

# Adapters for 'ISomeKindOfView' will be used for IAnotherAppView
# unless overridden by an adapter defined specifically for IAnotherAppView

IAnotherAppView = protocols.Variation(ISomeKindOfView)


class AlternateContactView(blah):
     protocols.advise(
         instancesProvide = [IAnotherAppView],
         asAdapterForTypes = [Contact]
     )

     # blah....


So, although I'm "hardcoding" couplings, components (and even sets of 
components) are cleanly reusable elsewhere.  Notice also that I'm adapting 
from type to interface, not interface to interface (although I could do 
that too), which means less typing.

Using a similar technique, it's also possible to add security declarations 
even to a base class, and similarly override them in context of an 
application that's reusing the underlying components.

The main difference between this approach and the Z3CA is that in my 
approach it's very easy to access adaptation context from code, while in 
the Z3CA it's easiest to access it via ZCML.