On 7/11/05, Frank W. Zammetti wrote:
Craig McClanahan wrote:
There are reasons to have an "application scoped" front controller.
There are reasons to have a "view-scoped" front controller. There is
*no* reason I am aware of that requires these controllers to be the
Good point. In fact, I don't think it would take much to convince me
that it's better if they ARE NOT the same :)
In Shale, the application-scoped functions are performed by a Commons
Chain pipeline that is configured and processed by Shale's filter.
This is the right place to put things like "if the user isn't logged
on, redirect to the login page" and "log every request" type
functions. But it is not the right place for "execute this expensive
SQL query, but *only* if I am the view that needs it.".
This sounds very much like the types of things I would typically do in a
filter. I'm a fan of filters because it's one less piece of the
puzzle that doesn't tie me to a particular framework (I've done some
converting of apps from one framework to another, so I always keep the
possibility in mind as much as possible).
Is there a benefit to the Chain approach over filters?
In this case, the only purpose of the Shale application filter is to
execute a Chain that is applied to all requests. So have it your way
Seriously, the reason for that choice was to reduce the amount of
effort needed to add a particular piece of application scope logic.
It's a lot easier for a newbie to implement a Command, and then add it
to a configured chain, without having to understand the whole
processing flow of a Filter. The only tricky bit is whether to return
true or false from the execute() method :-).
On the other hand, use of the Shale application filter does *not*
preclude you from using other technologies (like securityfilter) that
are also based on filters. One of the key lessons I've learned is
that frameworks should be fine grained, not monolithic ... make it
*easy* for your users to incorporate additional capabilities. Filters
are a huge enabling technology that are free for the taking if you
assume a Servlet 2.3 or later baseline (as Shale does, but as Struts
1.x has not as yet). So, if you like filters, go for it ... they'll
work fine in a Shale environment.
In Struts 1.x, you get around the latter case, typically, by having a
setup action before the view, and a process action after the view.
Shale simply combines those two bits of code into a single class (and,
along the way, combining the form bean too), resulting in a little
less code, but a lot fewer classes.
I think I just realized why I'm not completely excited by this... I've
never been a fan of DispatchAction, and while I understand it isn't
exactly analogous, it is along the same lines.
You couldn't know just how ironic me saying that is, but trust me, it is
:) Probably 6 or 7 years back I had some rather heated debates with
some coworkers where I was trying to convince them it was better to have
a single class with a switch block than a couple of individual classes
(this was before frameworks were en vogue, so we were talking servlet
design). I've done a complete 180 on that, to the point where I,
generally, won't use DispatchAction.
It was, until now when I realized it, giving me a subconscious dislike
of anything along those lines :)
The JSF recommended pattern actually lets you do "dispatch action"
sorts of things, but a bit more easily :-). The key is that you can
bind different submit buttons to different execution methods ("action"
methods in JSF terminology) -- and those methods can either be in the
same class or in different classes. Both have nice advantages:
* If you have a search widget on every page of your app, you can
bind all of them to a single common action that performs the search.
Coupled with outcome-based navigation, the developer implementing
the search functionality doesn't have to care anything about navigation --
his or her only job is to report back on what happened (for a search
widget, typical results would be "no matches", "one match", or "multiple
matches" ... which the application architect can map to a single view,
two views, or three views at his or her whim -- *without* changing any code.
* If you have, say, an "Update" button at both the top and the bottom
of a long table, you can bind them to the same action, since you want
exactly the same behavior -- you are only providing two ways to invoke
it as a convenience to the user (GMail users will instantly recognize this
as the paradigm that is used for the "Newer" and "Older" buttons in the
People do that with form beans already, so we clearly haven't
succeeded in communicating the correct pattern :-).
Agreed. And I for one cannot claim to have always gotten it right either :)
It's not about mixing layers. It is about mixing all the parts of the
*same* tier (view) related to a particular page into a single class,
instead of three classes (setup action, form bean, and process
action). The adapter has to be somewhere no matter what; co-hosting
it in a single class turns out to have benefits in terms of simplicity
and unit testability.
While I agree on the unit testability point, I'm not completely sold on
the simplicity argument... there's always a fine line between how much
actual code there is and how big the object hierarchy is. Go too far
either way and its complex, just in different ways. Again, I've changed
my opinion on this, but I now feel that a larger number of classes,
assuming each has a clearly defined role to play, is easier to digest
than a single class with all the code, or perhaps even a little more
code, in it. Again, there is a bit of a fine line there because if
there are too many classes, no matter how simple, it becomes difficult
to see how they all fit together.
Don't assume that the entire user population knows, or even *wants* to
know, what an "object" is. It would be a disservice for the Java
platform as a whole to sneer at such people -- instead, we should
embrace them. The more Java people there are, the more folks will buy
our Java related products (and the more places we can go get jobs if
we get tired of our current situation :-).
In 1.1 and 1.2 JDKs (i.e. when Struts was invented), this mattered a
*lot*. In 1.4 JDKs, it basically doesn't matter unless you have
*huge* request volumes. Thus, the reasons for most people to not put
their adapters in request scope is basically gone.
That's good info, thanks! :)
I wonder, and I'm not the first one I'm sure, what would it take to make
Struts work that way now? More importantly, what would the consequences
be? It seems like it could be done in a completely backwards-compatible
way, at least at first pass through my brain.
In today's world, if you are doing *new* development, the choices are
actually pretty harsh:
* If you want the Action+ActionForm paradigm by itself, adopt WebWork.
They got a bunch of the other stuff right already; it's not worth reinventing
* If you like component oriented architectures, pick JSF (if you like
or Tapestry (if you like the edge). In either case, it's not worth
in 2005 ... or competing with a JCP standard technology that has achieved
(in its 16 months since 1.0 release, pretty much the same communty
support -- books, tutorials, consultants, etc. -- that Struts 1.x
Can you tell I'm not personally sold on trying to retrofit Struts 1.x
to match today's patterns? That doesn't mean it should not be done,
or that it's a bad idea ... it just means that I have no energy to
invest in that direction. It's time for a clean break (not unlike the
changes from Apache HTTPD 1.3->2.0, or Tomcat 3.x->4.x, where
completely different architectures were inserted to leverage the most
recent best practices).
(By the way, I'm now quite happy that I didn't waste time trying to
learn how to build Maven 1.x build environments, since Maven 2.x
basically throws that stuff away :-).
Just remember ... the lifetime of Struts 1.x (five years since initial
conception, four years since 1.0) is basically a geologic era in terms
of Internet time :-).
Absolutely! You must have gotten *something* right for Struts to have
this kind of staying power :) I can think of many things that seemed
like the greatest thing since sliced bread at the time that wound up
fading into obscurity in half that time.
Of course, the above advice is primarily for folks doing new
development -- people with existing investments in Struts 1.x should,
of course, be aware that their investment is being protected by
ongoing development on 1.2 (then) and 1.3 (now). That will continue
as long as there is a need for improved capabilities.
But that's not where the future of web tier development in Java lies,
IMHO. After five years of creating the de facto standard, it's
definitely time for me to leverage five years of lessons and do it all
over again. But this time, founded on a JCP standard technology so I
don't have to argue with anyone about adopting some wildcat open
source project for their mission critical application architecture
To unsubscribe, e-mail: firstname.lastname@example.org
For additional commands, e-mail: email@example.com