[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.