|
|
|
The Zope Component Architecture: To a hammer, everything looks like a nail.I have experienced issues with the Zope Component Architecture. This is the first part of a series. ComplexityThe feeling of complexity comes from the fact that some few very abstract concepts such as interfaces, adapters, and utilities are used all over the place to represent all sorts of more familiar concepts. The Zope3 code leaves the programmer in the situation of a researcher attempting to decode a DNA sequence, i.e. when one is looking too close it is difficult to see. An exampleTo find a book by its name, intuitively one would write something like:
>>> from my.app import registries
>>> print registries.getBookRegistry().getBookByName("The book on Zope")
once the 'registries' have been imported, the code completion comes for free (CTRL+space when using an IDE like Eclipse): - registries => getCarRegistry() => getListOfCars() ... - registries => getTypeManager() => getTypeByName() ... ... which means that the API is made available by simply typing the words in English. One expresses the same idea in Zope3 as: >>> from my.app.interfaces import IBook >>> print queryUtility(IBook, name="Book on Zope") ... which amounts to the same quantity of code, but with reduced understandability because that begs the question:
(in fact it returns a book, not a utility) This forces the brain to handle two foreign concepts (interface, utility) in the place of two otherwise familiar concepts (book registry, book) Of course there is no such equivalent 'code completion' feature possible in Zope3 since utilities are registered at runtime (in ZCML). Also to find books one needs to know that they implement the IBook interface and that they are registered as utilities under a name. Another exampleTo get the type of the book, one would write in English: >>> book = Book(type=PAPERBACK) >>> print book.getType() but in the spirit of the Component Architecture one would use "interface types", instead: first by registering book types: >>> class IBookType(IInterface): >>> """The book type"" >>> class Book(object): >>> implements(IPaperBack) >>> alsoProvides(IPaperBack, IBookType) or even in ZCML: <interface interface="IPaperBack" type="IBookType" /> and then by querying the interface type on the book instance: >>> book = Book() >>> print queryType(book, IBookType) It always take me a few minutes to figure out what is actually happening, hence I am not 100% sure that the code is right this time. more and more complexityIt should also be noted that the recent refactoring of ZCML directives which aimed at removing "redundant" directives because they could be expressed in "simpler" terms as adapters or utilities does not really simplify the task. Now a factory is a utility providing zope.component.interfaces.IFactory. We are getting closer and closer to a complete ternary representation (interface, adapter, utility) of the world, which I am sure is an elegant concept, but for the abstract thinker only. Conclusion: To a hammer, everything looks like a nail.Comments
Posted by Jean-Marc Orliaguet @ 09/29/2006 12:18 AM.
-
7 comments
|
Latest blog posts
Latest animations
Latest documents
|
||