Last changed: May 22, 2005 17:55 by
Andrus Adamchik
Fresh impressions about Tapestry from a recent project. Version used is 3.0.3. And surely it shows my WebObjects
bias, and probably a few misunderstandings.
Things I like about Tapestry (things that make it like WO or better than WO):
- It works. It is not Struts and has no JSP underneath. It helps you to get things done.
- It has the right main abstraction (hierarchical components with bindings).
- It uses OGNL
for bindings.
- With Spindle Eclipse plugin
templates behave "half-compiled" (e.g. if you rename a class, you'll see a red mark in a bindings file telling you to fix the class name; however if you rename a getter or setter method, Spindle doesn't detect that).
- It allows bindings straight in HTML template.
- It can attach a dynamic component to an arbitrary HTML tag using "jwcid" attribute. So there is no <tapestry> tag.
- It has a Block component (a WOSwitchComponent analog on some serious steroids).
- Highly configurable "application stack" (Engine, EngineService, Visit).
Things I don't like about Tapestry. Some of these have negative effect on productivity and design, some just on my mental health. I believe many (but not all) of the items below will be fixed in Tapestry 4.0.
- Life-cycle method names are confusing (e.g. "initialize()" is not really "initialize"
)
- This bites all WO developers. For some mysterious reason page instances (instead of just templates) are pooled and reused across requests. Therefore whenever you "enter" a page to render a response, you have to completely reinitialize its state. Forget WO transparency in storing page state (and handling back buttons). As a result you'll have to write code for things you'd get in WO for free (ok, for $700
). Page state handling is a topic of heated discussions on tapestry-user list. Clearly other users are not satisfied with it either.
- Core component library has a number of inconsistencies and workarounds (I think this part will actually be improved soon). E.g. there is a repetition component called "Foreach", but you can't use it if you are iterating over the form fields. You'll need to use "ListEdit" component with an arcane model interface.
- No WOBuilder analog. I like Spindle, but at least a minimalistic WYSIWYG support would go a long way.
- I had action methods in the form called in the middle of "rewind" phase (aka "takeValuesFromRequest"), when not all data is read from the form yet! I had to implement an ugly workaround that would wrap action processing code in a "Closure" inner class instance that is passed along with request cycle and executed later when the form bindings are fully processed.
And finally things that are "different", I am not yet sure whether they are good or bad:
- At times I have a feeling I am coding in Swing (an analogy Howard often uses himself) - everything is compiled (good), but takes forever to code (bad). In other words it takes more time to write your program, but less time to debug.
- Another WO gotcha. There is no "takeValuesFromRequest", instead Tapestry would rerun its analog of "appendToResponse" in "rewind" mode. It takes time to get used to it.