Hey, I'm curious about what's in the works for Tap 5. The ideas
bouncing around in this thread sound very promising.
Let me just give a bit of background, first.
• I'm involved in an enterprise migration from PHP to Java. We've got
a lot of users (as of now, 20K concurrently, with an attractive
growth curve)—our scalability requirements are pretty heavy.
• My professional experience is predominantly with .NET, but NeXT
technologies (WebObjects :) inform my design sensibilities.
• After a load of research, I've settled on Tapestry for e-commerce
and administrative applications. But we're expecting to use a lot of
AJAX and are architecting for 100-200K concurrent users, so I'm not
sure I'll be able to use it for our customer application.
• I haven't dug into the framework as deeply as I might just yet, but
it's the only Java component system that seems supported and useful.
(JSF is a train wreck!) I see WebObjects in Tapestry, and I like it.
• The separation of design concerns from component initialization and
code is absolutely vital to our organization. (Not so vital is the
separation of component instantiation and binding from code, but I'd
rather see that in data than in code.) Localization support is vital.
Note that this means that inline component instantiation is not only
redundant, but undesireable and destructive. I'm going to have to
review my developers' code to ensure that they don't use it, because
it complicates localization!
My biggest concern with Tap 4 is that it's bloody confusing. Just
switching to a component-oriented outlook from a code-oriented
outlook is a big switch for most young developers. Binding and
iteration variables are tough to grasp. To my more junior developers,
I have to explain why using instance variables in servlets is a no-
no, and I get bewildered blinks when I mention threading. Extending
that conversation to component instance pooling is another couple
layers of abstraction away; to understand why pooling instances is
useful, they need to understand the threading model, then consider
the expense of building a component tree, and etc. There are a lot of
mental hurdles involved. The inheritance-based model is the worst
wart, though; it seems predominantly driven by the need to clean up
before re-pooling a component.
By contrast, my developers would be very comfortable with ASP.NET 2's
code-beside model, which provides a much stronger guarantee of
cleanup and thread-safety and a vastly simplified programming model—
by throwing away the component tree at the end of the request cycle.
Note that ASP.NET control are conspicuously lightweight, so building
the tree isn't necessarily too expensive. And certainly not after
considering the cost of executing them. On the other hand, ASP.NET
data binding and component reuse are seriously flawed; these are the
areas where I'm looking forward to using Tapestry. But— the component
advantages don't mitigate Tapestry's convoluted programming model.
I hope that's a good overview of how I feel, coming at Tapestry as
something of an outsider. It has warts, but it seems like the best
solution going, and one which has proven to have more staying power
than even the big-name competition.
Now, here are the things I'd love to see in Tapestry 5…
• Don't make us write abstract classes! That's five files I need to
write, now, to author a page with a testable controller: Foo.
{html,page,java} for Tapestry; plus MoreFoo.java for my real
controller that I access with an indirection from Foo; and
MoreFooTest.java for my unit tests. And despite all that typing: I
can't test anything in Foo.java, and I have to add an extra
indirection to virtually all of my bindings.
• Don't reuse component trees! Or, at least, let us not do so.
Imposing the “clean up after yourself” contract on page developers is
a big, uncomfortable requirement. Loosening that obligation, however,
wouldn't be a breaking change…
• Don't make our code-behind files derive from any class. This
removes a great deal of uncertainty when we attempt to unit-test our
controllers. Perhaps the controller class can be thrown away after
each request cycle, while the component tree could be cleaned up and
recycled; this might be a best-of-both-worlds thing.
• Refocus codegen on providing simplicity and performance rather than
adding complexity. Codegen right now seems focused on making instance
reuse safe, at the expense of complicating the programming model.
Instead, apply codegen to make binding fast (compiled OGNL?), and on
speeding up instantiation of component trees.
Am I sounding like a broken record? :) Probably because I think the
big problems with Tapestry seem to stem from one cause…
Anyhow, thanks for reading. I'm sure I have a number of
misconceptions; please don't be too brutal. :)
— G