Article View: cn.bbs.comp.lang.java
Article #12202Beyond MVC: A New Look at the Servlet Infrastructure---zt
From: ���|{�����ɱ�}
Date: Tue, 03 Aug 2004 07:54
Date: Tue, 03 Aug 2004 07:54
1305 lines
53034 bytes
53034 bytes
ԭ�ij�����http://today.java.net/pub/a/today/2003/12/11/mvc.html?page=1
Beyond MVC: A New Look at the Servlet Infrastructure
by N. Alex Rupp
12/11/2003
This article is the first of two that examine in depth the origins of the
Model-View-Controller (MVC) design pattern and its misapplication to servlet framework
architectures. The purpose of this first piece is threefold. First, it attempts to provide
an accurate description of the problems brought about by MVC in servlet middleware. Second,
it suggests techniques and strategies for coming up with a new design, one better suited to
the needs of servlet infrastructure developers. Third, it offers an example of a completely
new, nonderivative pattern we might use moving forward. The second article backs up my
assertions by introducing and exploring a reference implementation of the new design.
Ultimately, my goal with these two articles is to convince the servlet middleware community
once and for all to put the dark days of MVC behind us and to lay the groundwork for
completely new, nonderivative servlet middleware architectures that better address our
common needs. Please bear with me; I wouldn't write a piece about MVC in the servlet tier
unless I believed it was a funeral dirge.
Part One: History of the MVC Pattern
We begin with a historical account of MVC's origins in the early 1970s and its subsequent
use as a pattern for thick-client UI component frameworks.
Tracing the historical origins of the Model-View-Controller pattern is not a difficult thing
to do. The man who brought us MVC has published historical documents that date back to 1973,
when object-oriented programming was still being conceived and scientists were only
beginning to explore the concepts of "distributed, communicating components." (See
Reenskaug, Trygve, "The History of MVC.")
Following the paper trail back to the early days of object modeling is instructional in two
ways. First, it serves as a reminder that the problems we face today in distributed
computing are by and large the same ones faced by computer scientists from three decades ago
�� in other words, the proverbial wheel is still in dire need of reinvention. Second, it
shows us how much we still have to learn about simplifying complex systems.
Oslo Norway, 1973
In August of 1973, Dr. Trygve Reenskaug, while working for the Central Institute for
Industrial Research in Oslo Norway, wrote a paper called "Administrative Control in the
Shipyard," which he presented at the first International Conference on Computing
Applications in Shipbuilding that autumn. In his paper, Reenskaug analyzed the modern
shipyard as an information system. In this exercise, he identified many of the technical and
social complexities inherent in shipyards and suggested several techniques that could be
used while describing the system. His goal was to reduce the overall complexity so the
shipyard could be more easily modeled in a computer application.
If the goal of a component framework is to reduce complexity for developers modeling an
information system, what strategies can the framework designer use to make this possible?
Early on, Reenskaug touches upon the idea of "distributed, communicating components." His
strategy is that the "total system will be decomposed into a number of components" (emphasis
his; see Reenskaug, Trygve, "Administrative Control in the Shipyard"). Decomposition of a
large or complex system into modular components played a central role in his strategy. By
now, most of us understand this concept very well. We call it the "Separation of Concerns"
of architectural components.
Following this strategy, Reenskaug begins to describe "a general framework" whose "main
purpose is to enable us to mold a new information system to fit an existing way of
organizing things, the resulting system being sufficiently flexible to be easily adapted to
changes in the organization." (ibid.; emphasis mine.)
He then outlined several "major requirements [of] systems developed within the framework."
(ibid) The following behaviors are those that the framework should seek to enable:
We want to build man-machine systems. Manual override on automatically produced results must
be a routine matter, and the systems must be able to compute the consequences of such
overrides.
Responsibility, authority, and competence will be spread out among groups of people in the
shipyard. Our total data processing system must be divided into subsystems that are attached
to the various areas of responsibility. The subsystems shall be controlled by these groups
and further developed by them.
A subsystem must be transparent to its responsibility group, so that its owners may fully
understand their system's behavior.
All subsystems must be open-ended, so that they may be attached to other subsystems
belonging to the same or other responsibility groups.
The total system must be capable of continuous growth; it must be possible to add new
subsystems or change old ones without disturbing the total system. It must be possible to
include "foreign" systems developed by other people without upsetting the total system. The
painful transition from one "generation" to the next can no longer be tolerated. (ibid.)
A condensed list of these requirements would read:
Simplified manual override.
Divisible into modular subsystems.
Behavioral transparency of subsystems.
Subsystem modules are pluggable.
The total system is capable of continuous growth.
Despite the solid foundation that Dr. Reenskaug had laid out for implementing his framework,
the lack of an object-oriented programming language stalled progress on what was to become
MVC. It wasn't until several years later, in California, that he got access to the world's
"first personal computer, the ALTO, with its powerful direct manipulation interfaces." It
was at this time that he began experimenting "with tools for end users manipulating their
part of a total plan." (see "The History of MVC")
Xerox Palo Alto Research Center, 1978
This experimentation took place at the Xerox Palo Alto Research Center (PARC). Access to the
ALTO helped Dr. Reenskaug identify the end user of a distributed system. Dr. Reenskaug and
his colleagues devised "MVC as a solution to controlling a large and complex data set."
Their task was similar to the task he'd defined for the component framework in 1973 �� to
reduce the complexity inherent in presenting an interface to the system. This time, the
"subsystem" was actually the user interface.
Describing a new framework for accomplishing this task was not easy �� it never is. "The
hardest part was to hit upon good names for the different architectural components,"
Reenskaug writes. "Model-View-Editor was the first set," In his "Thing-Model-View-Editor"
paper (see Reenskaug, Trygve, "Thing-Model-View-Editor"), Dr. Reenskaug defines the
following terms:
Thing: "Something that is of interest to the user." (A real-world concept.)
Model: "An active representation of an abstraction in the form of data in a computing
system." (Abstraction of the Thing.)
View: "One or more pictorial representations of the model."
Editor: "An interface between a user and one or more Views." (Later called "Controller" and
"Tool.")
Out of these early prototypes, MVC Triads emerged in SmallTalk-80. The model was an
abstraction of the real-world concept, the view was its visual representation, and the
controller was the buttons and slider bars that allowed the user to interact with it
(thereby "controlling" the view). All pieces in the triad were interconnected and could
communicate with the other two pieces, so there was no layering or abstraction involved.
Since then, Reenskaug has "preferred to use the term Tool rather then Controller." According
to his notes, these are the terms he has used in later implementations (see "The History of
MVC")
Shortly thereafter, Dr. Reenskaug left the PARC laboratories and his work was carried on by
Jim Althoff and Dan Ingalls. Because of this early work, UI Development in ST-80 was greatly
simplified, and the MVC pattern continues to this day to be an effective and appropriate
solution for the design of user interface components.
MVC Pattern Language
It is important while we are studying and using MVC that we bear in mind the original
purpose of the pattern: to reduce the complexity of user interfaces for a large and complex
information system. It was designed for a specific purpose and evolved to meet a specific
need.
Dr. Reenskaug's work in MVC has not been abandoned. Earlier this year, he began publishing
material on his new MVC pattern language.
Nowhere, ever, in any of his papers was it suggested that the MVC pattern could be used to
address the needs of n-tiered workflow processing infrastructures. But here we are, 24 years
later, trying to pound in nails with a screwdriver. Despite the careful effort of scientists
from Reenskaug's generation, it seems that we've not learned a thing.
E-mail Print Discuss Blog
Beyond MVC: A New Look at the Servlet Infrastructure
Pages: 1, 2, 3
Part Two: The Servlet Framework Antipattern
At this point, we're going to try to break through the recent buzz surrounding the MVC
pattern and illustrate how, despite its success in traditional UI frameworks, MVC fails to
address the needs of servlet framework architectures and the framework development
community.
But before we go any further, I'd like to define the terms "pattern" and "antipattern," so
that the reader understands the context in which I'm using them throughout the remainder of
the article. I borrow my definitions from the book AntiPatterns and Patterns in Software
Configuration Management by Brown, McCormack, and Thomas.
"A Pattern is a form of solution intended to address a problem. The problem for Pattern
readers has always been to identify when and how a Pattern should be used."
An AntiPattern is defined as "a commonly occurring solution to a problem that generates
decidedly negative consequences;" in other words, an AntiPattern is generally a commonly
repeated practice in industry that is flawed in some manner and causes symptoms that are
more undesirable than whatever positive results were sought.
Design patterns can become dangerous in a development community when their popularity
eclipses their ability to address the evolving needs of a development effort. By
implementing patterns for their own sake, without a critical evaluation of their ability to
describe the practical concerns of an information system, we contribute to the spread of
antipatterns in our development community.
Some antipatterns are easy to identify and with a little effort can be easily avoided.
However, some are not. At first blush, many antipatterns are indistinguishable from
beneficial design patterns. They spread by giving us a sense of security and confidence in
their use. By reducing them to advertising buzzwords, we re-enforce the perception that they
are widely accepted, address a common problem, or confer some predictable advantage, outside
of the context of their original use. There are no "one-size-fits-all" solutions when it
comes to information system design. A pattern might confer advantages within a given
context, but outside of that context, all bets are off.
To make matters worse, technical, economic, and social circumstances can also contribute to
the "silver bullet" mentality surrounding the antipattern, further contributing to its
popularity in the community. The inevitable resulting misapplication of the antipattern can
introduce new complexities into our software and conflict into our community.
Pressure (whether real or imagined) to conform to the antipattern is often greater than the
technical or economic need to abandon the practice �� at least in the short term. Time lends
a different perspective to matters, however, as what Reenskaug described as "the painful
transition from one 'generation' to the next" becomes incrementally more difficult to avoid.
Unwieldy, Inflexible Architectures
Although the Model-View-Controller design has proven itself throughout the years to be an
appropriate and beneficial pattern for modeling user-interface components, its use in
designing distributed servlet infrastructures has led to very unfortunate results. Among
these are the advancement of unwieldy, inflexible architectures that are incapable of being
quickly altered to support the ever-changing demands of the technological and economic
environment.
On October 19th, 2003, on the Struts development list, a user suggested the addition of a
feature his business had found lacking from the framework. His suggestions were given a fair
but brief consideration and never brought up again. This is not because the Struts community
is apathetic to the needs of its users �� nothing could be further from the truth. These
people write software that they give to the world for free.
The most likely reason they didn't implement his change is because it would have required
rewriting several core classes in their infrastructure and would probably have introduced
unwanted complexity to the application. In addition, it is questionable whether or not this
particular feature would enjoy a broad enough use to warrant inclusion into the default
feature platform for Struts. As a result, the novice developer and his company are forced to
rewrite portions of Struts to add crosscutting, system-wide behavior. There is no ability to
plug in crosscutting system logic or to easily extend the feature offering of the platform.
In this way, Struts has failed to pass Reenskaug's second, fourth, and fifth requirements,
that "the total system must be capable of continuous growth, it must be possible to add new
subsystems or change old ones without disturbing the total system. It must be possible to
include 'foreign' systems developed by other people without upsetting the total system." He
stresses the point twice, and for good reason �� the only guarantee we have in technology and
business is that our needs will change. Systems that are incapable of changing in a fluid
manner will inevitably fail to meet our needs, and we will find ourselves facing the
difficult challenge of migration to the next generation.
Fragmented Development Community
Another unfortunate side effect the MVC antipattern has had on our community is the
fragmentation and polarization of its members, who have in recent years become entrenched
around dozens of incompatible technologies. Business leaders are forced to choose between a
myriad of nonstandard options, whose feature offerings largely mimic each other.
Earlier this year, I began exploring WebWork as an alternative to Struts. While Struts had
been the first framework to separate the command URI from the underlying logical system
(thus separating the concerns of the end user typing in a URL from the developer chaining
together actions in the servlet tier) and to introduce a rough workflow processor, WebWork
was beginning to introduce the concept of interceptor chaining and a dynamic value store
that used an expression language for parsing through the contents.
But at the time, the WebWork advocates were focused on the differences between Rickard
Öberg's implementation of MVC and the Struts implementation. The documentation has improved
quite a bit since then, and the reader might get a sense that MVC is no longer the selling
point it once was. At least a half-dozen MVC derivatives have been introduced into the
community, but none have met with great applause. A good friend of mine swears he went to a
presentation by Craig McClanahan where he brought up a diagram of MVC and there were four
boxes. Model, View, Control and ... ? There have been so many half-hearted explanations
about how "actions are really Controller components and ..." ad nauseum. I'm sure you've
heard it all a hundred thousand times.
The point is that no matter how you cut it, spin it, twist it, melt it down, push, pull, or
try to explain it, no matter how many books you write on the topic, nobody has ever been
able to adequately explain how an n-tiered servlet component infrastructure is supposed to
implement the Model-View-Controller pattern.
And as a result of our insane quest after this philosopher's stone, we've managed to
splinter what could otherwise be an extremely large and potent section of the development
community.
Rising, Ongoing Opportunity Costs
But worst of all, aside from the obvious conditions brought about by our stubborn adherence
to this antipattern, we must also factor in the ongoing opportunity cost of our failure to
build a common, extensible, flexible servlet component infrastructure that meets the
continuously changing demands of the market and is positioned to take advantage of the
technological progress that is happening all around us. In the meantime, the main
competitors to J2EE are capitalizing on the unreasonable complexity involved with bridging
the web-persistence gap.
Beyond MVC: A New Look at the Servlet Infrastructure
Pages: 1, 2, 3
Part Three: Refactoring the MVC Pattern
In this third and final part of the article, we retrace the footsteps used by Trygve
Reenskaug to isolate the MVC design pattern and apply his modeling techniques to the servlet
framework tier. We also introduce a new design pattern that specifically addresses the needs
of servlet framework developers in the J2EE sphere.
Fortunately, we're not bound to the MVC pattern. If we're willing to do some legwork, the
techniques developed by Dr. Reenskaug to arrive at an appropriate design for the problem of
servlet framework architectures are at our disposal.
While we're designing this new pattern, we must keep in mind the five requirements listed
above for a component framework. We know that we must create a system that can be decomposed
into modular components, that the behavior of each subsystem component should be transparent
to the larger system, that components should be able to plug in to the larger system, and
that the system should therefore be capable of continuous growth without adding complexity
or management chokepoints to the development process. Finally, the inner workings of the
system should be subject to some form of manual override, wherein a manager can redefine the
system behavior at runtime without taking it offline.
Concerns of Architectural Components
We have to start by considering the different roles that different objects play in our
system. There are only a few higher patterns of behavior for all of the different
architectural components in a servlet framework. If we are able to isolate those behaviors
and capture them into interfaces, then our system will become more flexible and modular.
By considering the nature of the different components in a servlet framework and employing
basic separation of concerns, we arrive at three different roles for objects �� three higher
patterns of behavior that can be observed in all existing systems:
DataSource: In the most abstract sense of the term, this is a place from which data can be
gathered and stored. It could be a message bean, a request object, or a map, and would have
a set of very simple method signatures similar to a map.
Action: An action is the basic logical building block of a business system. Actions are all
executed and needn't necessarily know the order of their execution.
Workflow: The core concern of the servlet framework is to manage the execution of a sequence
of Action objects using one or more DataSource objects. The internal logic of the framework
that determines the flow of control over the request can be isolated in a Workflow
interface.
And what about presentation components? First, bear in mind that the user interface for a
system needn't necessarily be visible. It could be audible or thermal or even olfactory, so
"View" components is an inappropriate and limiting term. Second, considering the
requirements, it follows reasonably that our framework should easily plug into any type of
presentation technology, several of which are becoming extremely advanced and needn't be
replicated.
Trying Out the New Design
How do we know this would work? Let's try applying this new design concept to a simple
application like a card catalog, and if it doesn't work, out we'll refactor. The data
written on the cards should probably be kept in some kind of DataSource objects so it can be
stored, retrieved, examined, and altered. There are many different types of data object
solutions. EJBs, POJOs, and XML are just a few �� the list goes on for miles.
Next, we'll want to operate on the data in the cards. Pulling them out of storage, putting
them back in, shuffling them, erasing their contents, using them as coasters, etc. This
logic can be encapsulated in actions (preferably as fine-grained as we can get them). If we
break down the actions into small enough pieces, we can use them in different combinations
to get different effects.
The decisions governing the order in which these action combinations are executed represents
the application's workflow. To encapsulate this logic, we can write a series of workflow
controllers whose job is to execute actions in a certain order. This workflow could be
hard-coded into the program, but it would probably be better if we incorporated a dynamic,
rules-based system like Drools, so that the workflow logic could be controlled and altered
at runtime to meet the changing needs of the business.
Of course, all of the different, dynamic rules approaches require some kind of external data
for directing traffic. Do we need to refactor the design and add another category for
components? Not at all �� workflow descriptors and user input are just two more types of
DataSources.
The actual human interface for the web application can take place in another tier, and its
developers can use whatever solution they like for building their components. They can share
access to the same DataSource components, and can implement their own presentation
components and tools for manipulating the data however they want. If they're smart, they'll
probably use MVC or some variant in their component design, because UI is where MVC shines.
Abstracting the Feature Platform
If we were able to break down system in this interface-heavy manner, we would be able to
abstract the actual features provided by the platform. Things like form validation, value
caching, dynamic EJB bridges, security integration, and other actions could all be
abstracted into a platform that actually rests on top of the underlying workflow system (or
plugs into it �� I say potato ...). At that point, developing feature platforms of useful and
common actions could be a cooperative community effort. Businesses could develop their own
libraries to implement application-specific, or even system-level, actions without having to
alter the underlying workflow system or even know how it works, and development teams could
combine their efforts to build libraries of mission-critical action components for common
use.
The interface-heavy design could also potentially allow us to swap out entire portions of
the workflow or action subsystems at runtime and replace them with custom, more specialized
subsystems that are tailored to our individual needs. Imagine: exchangeable parts for
servlet frameworks. With Maven, we could dynamically assemble the framework and feature
platforms at build time from specialized component subsets.
But it doesn't have to stop there. The social benefits of such a flexible, modular, and
extensible system should be obvious. The different factions of the development community
could reassemble around implementing commonly needed features instead of warring over
architectural minutiae. Businesses could develop strategic, proprietary feature platforms
that are fine-tuned to the needs of their companies, or could collaborate on common
component libraries without having to get their changes accepted by the team developing the
workflow core.
And perhaps the best news of all is that the investments we've already made into the feature
platforms of different frameworks could easily be ported to this new infrastructure.
Features from Struts could be rewritten as action platforms and plugged into the framework
without a hitch. It might even be possible to write compatibility layers for existing action
implementations, so that the end users don't suffer unnecessarily in making the transition
forward.
Results and Conclusion
We all have this task in common: to implement a framework that will reduce the complexity of
bridging the web interface to the application server, and to do it in such a way that it is
flexible, extensible, and capable of constant mutation throughout the coming years.
As open source middleware developers, we also share a common desire to improve ourselves,
our businesses, and our communities by collaborating to build better tools. The time is long
overdue for each of us to reconsider our assumptions about the MVC pattern, to acknowledge
the negative effect it has had on our community, and to work together to address the
problem. We need to reevaluate our common technical and social needs, overcome our
stubbornness, and completely abandon the MVC design as the cornerstone of the servlet
framework architecture. A new solution is waiting that addresses those needs.
In the next piece in this series, I'll back up my assertions with actual code and introduce
the Shocks Servlet Framework, a full implementation of the design I've outlined here. I'll
go over the architecture of the framework, discuss how it evolved conceptually, and show how
it addresses each of the five challenges for frameworks Dr. Reenskaug laid out over thirty
years ago.
N. Alex Rupp is a professional Open Source developer and software architect for Open
Technology Systems, a Twin Cities firm dedicated to helping small and medium sized companies
participate in the Open Source software movement.
View all java.net Articles.
Is MVC really an antipattern for servlet architecture? Do we need something else?
Showing messages 1 through 26 of 26.
Trackback from HatShop
Quick thoughts on MVC
2004-03-11 10:33:41 [Reply | View]
Beyond MVC: A New Look at the Servlet Infrastructure got me thinking about the MVC design
pattern again. Of late, most of my work has been with PHP-based Open Source projects. Each
of them incorporate different design patterns. Most of...
Can someone clarify how the shocks example...
2004-02-03 07:18:29 rickcr [Reply | View]
I admit I haven't looked very closely at the shock framework but have used now for a pretty
long time. I was looking at the shocks workflow descriptor here
http://shocks.codehaus.org/example_code.php and I'm not sure how this adds that much more
benefit over struts?
I try to keep my Struts apps modularized as possible by having my Actions (actually dispatch
methods) return mappings to generic things such as "success" "failure" and then of course
it's up to the config file to then determine where you go from there. You can make sure your
action calls from your forms are then specific to the page you are on
(action="doUpdateFromXYZpage.do") Your Action classes (Controller) are then pretty
independent of the view. That being said, I'm definitely interested in looking at other
frameworks, as I'm actually curious to see how you can ever get a framework model layer to
be 'totally' unconcerned with the view. The place where you 'go' when you submit a form will
often have to know where it intends to go when it's done executing commands or whatever.
(Unique things come up where certain objects have to be put into scope, etc). I've looked
some at the commons-chain project and I do some benefit in that because I like the concept
of defining a chain of events all in one place. You can have Struts chain actions but it's
very ugly to maintain and there are other problems with it. I'm downloading shocks now but
it doesn't look like it comes with a working demo application? Is there a working example
application that I can look at it? Thanks.
Can someone clarify how the shocks example...
2004-02-03 08:23:34 n_alex [Reply | View]
This descriptor file is being phased out. It'll be replaced by a Drools DRL file in the next
alpha release. Also, all of the data in this file is loaded into a JMX repository at
runtime, and is manageable. That lets us replace an action mapping at runtime. Again, this
is being phased out.
I posted last night to the shocks-dev list that I'm just about ready to ship an alpha-3
release, and there should be a sample application included with that. In the meantime, you
can download the geronimo web console, which I wrote against shocks alpha-2. Unfortunately,
I couldn't get the alpha-3 release ready by the time the article ran.
War: http://shocks.codehaus.org/console.war
Src: http://shocks.codehaus.org/console-src.zip
You might have trouble building the source for the console, as it was designed to be built
as a module in Geronimo and the Geronimo project is presently in null space. I can't do any
more work on the console until I get the alpha-3 released.
In shocks, actions aren't responsible for determining their "success" or "failure". They're
only state mutators. Ideally, the course of action is determined by the business rules
engine--that means business rules are written and maintained by business people and not by
programmers. It's going to be a while before this is realized in the framework, but it
should be fun to implement ; )
Hope this helps!
Can someone clarify how the shocks example...
2004-02-03 08:25:10 n_alex [Reply | View]
> This descriptor file is being phased out. It'll be replaced by a Drools DRL file in the
next alpha release. Also, all of the data in this file is loaded into a JMX repository at
runtime, and is manageable. That lets us replace an action mapping at runtime. Again, this
is being phased out.
Let me qualify that statement! It'll be replaced by the DRL file in the alpha-4 release. I'm
finishing up the alpha-3 release right now : )
At least
2004-02-01 15:59:43 liskiew [Reply | View]
It is very usefull article and it should be taken under consideration by everyone. I was
almost sure that not only i have had problems to adjust MVC pattern to n-tier J2ee
application solution. It is always the same, we try to match words and definitions to what
we have already implemented. It is not good if we have to vote for and against something is
Controller or not. Shouldn't it be clearer? I'm already working for my own framework and
offten I can not get rid about MVC point of view (it is propably already in my gens) but
something in it does not work for me. I wiil trace your articles for sure :)
Thx for that, good work.
Nature of the system design
2004-01-09 10:22:56 complystill [Reply | View]
I believe these approaches drag out a seldom noticed criteria of our system design, mainly
ones with Web UI, the designed system is whether UI driven or UI triggered. A UI driven
system is somewhat in request-response fashion, the classic WebApp architecture, this is
what MVC will wonderfully satisfy. And a UI triggered system can have much complexer logic,
than a typical web application, so Web UI for such a system will much more like an
administrative interface than a user interface, so complexisity and modules and subsystems
will have more chances to grow and change, without needing changes on the web engine's
skeleton.
No examples of "krufty"
2004-01-07 10:30:32 crowmobe [Reply | View]
There is some useful information here, but the main point has been side stepped twice. Once
in this article and once in your shocks site follow up. If you are going to claim over and
over that MVC is not to be used in a servlet framework, we would like to see some concrete
examples of what goes wrong. It is not that I want to debate this idea. I might buy it if
you had anything to back it up with.
I don't see why you even wrote the analogy on the shocks site because it is even worse about
leaving out the key information that it claims to give. You could have probably made the
point in less than 17 steps,and leave out some of the redundant information, but that is
beside the point. The point is that once again you left out the meat of your whole argument.
On step number 7 of the analogy we actually get to see some of the problems that you would
encounter if you used a hammer to try to fix your car:
"none of the doors work, the lights are all broken, there are no mirrors and I can't get the
hood off or unscrew the gas cap."
This is great, but we don't get to see what goes wrong when you use MVC on servlet
frameworks in even this detail. It is left out. All we get is "krufty" in step 7 of the
problem space.
Basically you have written an article, and a follow up, and in both cases you have failed to
back up your main point.
The Meat of the Argument
2004-01-13 13:27:31 n_alex [Reply | View]
Dear Crowmobe,
It's like . . . we're not communicating : ) I think we disagree on what my main point is.
I apologize for not realizing that sooner. You want the "Meat" and you think the meat is a
specific example of how MVC doesn't work. Could you tell me one single framework in which
every component implements a "Model", "View", or "Controller" interface? Is the Form part of
the Model? For the sake of
argument, let's say "yes". What about the action--is the Action a Controller? Struts'
documentation claims it is. Then what the hell is an ActionForm? Why can't the roles of the
components be neatly separated? Why don't they implement interfaces so we can trade them
around as interfaces? I hope this helps you see the problem I faced earlier this year when I
was trying to extend Struts and WW.
You've got to believe me--Struts is awesome software and I absolutely respect the guys who
wrote it and the guys who maintain it.
I decided on purpose not to provide the specific example which drove me to write an
alternative framework, because I don't want to sit around and gripe about their software--I
appreciate the developers too damned much to do that. I wrote a little about it at
http://shocks.codehaus.org/extension_trouble_01.php though, and I'm going to compile a list
of submissions from the DOZENS of developers who've written me, describing similar troubles
they had extending the popular frameworks in the past. (send me an email, if you have had a
similar experience, and I'll add your story to the list).
If you (or anyone else out there) could kindly tell me a simple way to create a versioned
pool of Struts or Webwork action instances and make them available across class loaders in
the same JVM and manageable through JMX so that you could alter the order in which they
execute and swap out one for another at runtime, I'd be happy to write doco for Struts users
on how to do it, because I think it's a killer feature and we should be able to plug it into
Struts.
I hope that answers your question. That, however, is not what I consider the "Meat" of the
argument to be (and I'm sorry if we've kicked this topic to death). I could come up with
examples of how Struts and WW aren't MVC all day long (please at least assume I tried to
implement MVC before I gave it up). A
previous version of the article did just that, but the tone sounded malicious so I stripped
it and tried to make it more positive. The "how" is not the point of my argument : ) The
point is WHY they can't implement MVC. That's the "Meat" as far as I'm concerned. And the
"why" is absolutely irrefutable. Why can't
they implement MVC? Because neiter Struts nor Webwork is a thick-client UI component.
If you could offer me some explanation of how the entire WebWork or Struts framework is
really just a thick-client UI component and should therefore be designed like one, I'll give
it a fair and measured critique. I hope that helps answer your question, and I'm sorry for
the confusion. I'm going to republish
the first article in a month or so in a place where it can be amended and maintained.
I sincerely hope this helps. If not, I'm willing to respect our differences and agree to
disagree on friendly terms.
--
Alex Rupp
Great principles you've reminded us of...
2003-12-18 15:09:51 denka [Reply | View]
Will it be too off to apply the reconfigurability at runtime requirement to AOP stuff? If
so, will pointcut selectors have to be "Data Sources"?
Thanks for the article! Terrific work!
Not OO enough
2003-12-18 13:19:41 xod [Reply | View]
It's good that the less-than-OO MVC fad is starting to show holes. However you write
"...employing basic separation of concerns..." and end up once more with this rather
procedural separation of code and data. Why not employ true OO methodology and separate by
Domain Object instead?
Excellent piece of work!
2003-12-17 11:59:23 nicolasdijkstra [Reply | View]
I have to say i totally agree with your point of view about MVC.
I've always had the feeling that there was something missing whenever i desgined a web
application, tied to that antipattern.
I'm looking forward to reading your next and see an implementation of the design you've
outlined in the article.
Faulty logic
2003-12-15 09:56:59 ljnelson [Reply | View]
First off, I hate Struts the more I work with it. I think it is a terrible, overgrown
framework.
Having said that, I think N.'s argument comes down to something like this:
1. Struts is a servlet application.
2. MVC was applied during the development of Struts.
3. Struts is unwieldy.
4. Therefore, when you apply MVC to a servlet application, you get unwieldy architectures.
An equivalent argument runs like this:
1. It is currently raining.
2. It is currently cloudy.
3. Therefore, whenever it is cloudy, it is raining.
More at http://www.jroller.com/page/ljn.
Cheers,
Laird
Faulty logic
2003-12-16 09:49:07 n_alex [Reply | View]
> First off, I hate Struts the more I work with it. I think it is a horrible, overgrown
framework
Tell us how you really feel, Laird.
Laird, I'm concerned that your personal feelings might have interfered with your *own* logic
in this regard. It has apparently interfered with your boiled-down presentation of my
research. I urge the other readers not to take hateful rants like these too
seriously--they're usually more self-indulgent than constructive and productive. And
ultimately, code always speaks louder than words.
I've posted a logical summary of my argument at the Shocks site to address posts like this.
Hopefully it can show with a little humor what I'm trying to express here.
It's a very difficult topic to write about, and the temptation is always to let it devolve
into emotional and illogical rants like Laird's. I'm only trying to introduce some ideas to
an evolving and unresolved problem space. I had fun writing Shocks and I'm having fun using
it, but I don't expect anyone else to do the same. I'm more concerned about reexploring
these old ideas. So if the ideas from this writing are revived and other people begin
integrating these ideas (which are, I remind you, not my own) into their own work, I'll be
very satisfied.
I've gotten such great feedback and am learning so much about this problem space that I'm
happy no matter the success of my software project.
Best,
--
N. Alex Rupp
Faulty logic
2003-12-22 03:45:10 ljnelson [Reply | View]
Sorry; didn't mean for any of that to come across as mean-spirited (or illogical :-) ).
I guess I just think that MVC can work. It's hard to get right. And frameworks that do it
badly (like Struts, for example) are frustrating. I'm not sure I'd brand it as an
antipattern.
Anyway, cheers,
Laird
Based on an invalid premise
2003-12-15 07:12:36 sage_sam [Reply | View]
So far, I have yet to hear a valid point on the failure of MVC to meet the requirements of
the MVC framework.
The author picked one particular post on a highly active mailing list (the Struts User list)
as an example. Even assuming, despite the immense traffic on the list and ongoing
development of struts, that he picked a valid target for his criticisms his points and
discussion are invalid.
The author wishes us to believe that, because of one item, "Struts has failed to pass
Reenskaug's second, fourth, and fifth requirementsthat 'the total system must be capable of
continuous growth, it must be possible to add new subsystems or change old ones without
disturbing the total system.'"
Just to review, the points in question are as follow:
2) Divisible into modular subsystems.
4) Subsystem modules are pluggable.
5) The total system is capable of continuous growth.
It must be considered that the item that he points to has nothing to do with item #2. The
discussion that the author points to is about a particular implementation of core logic.
However, even if I concede that maybe it does touch on the issue of modules, there is a
larger item he fails to consider:
Struts provides the very capabilty the author challenges. Search the Struts list and user
documentation for 'modules' and you will find numerous hits--and not just because something
in the logic is called a module.
Struts' modules implementation does exactly what the author wishes us to view as a failure.
By simply pointing to a new struts-config.xml file in the deployment descriptor and
providing subcontext, we can create a new module. No other modules care about it unless thye
want to. It does not affect the other modules. Thus, modules can be added or removed per
needed business requirements. In this way, I would say that requirements 2, 4, and 5 are
completely met.
In regards to the specific item, it is possible to provide a new request processor via a
plugin or specified request processor in a module's configuration file. Requirements such as
that provided by the user pointed out by the author can be included or excluded on a module
by module basis.
If these three items are all met, then struts meets all requirements that the author laid
out. If this is true, his contention that Struts does not fulfill the MVC requirements or
meet the need is not true. As such, while I find the article an interesting discussion of
the history and nature of MVC, I must find his conclusion based on an invalid premise and
hence completely illogical.
Trackback from Marc, himself, his blogs, and you reading them.
An MVC-Terrorist
2003-12-12 15:36:12 [Reply | View]
Dropped in the box via e-mail: Beyond MVC: A New Look at the Servlet Infrastructure. Just
some days after making public some of my own views... And I'm really sold before it even
begins: ...my goal with these two articles...
Not Exactly Enlightening
2003-12-12 15:12:27 ocean [Reply | View]
I guess I stand alone but I thought the article was pretty silly.
The origins of MVC was kind of interesting but not exactly critical. And claiming that MVC
is an antipattern because the developers of Struts decided not to include some feature...
uh... Perhaps I'm missing something, but you never actually explained why MVC doesn't work
in servlets.
Next, there are several well-known problems with the solution you propose. Using Maps as
your model? It's been done several times and it always turns into a maitenance
nightmare--either that or developers end up writing static accessor methods like
OrderUtils.getPrice(Map). Next, the Action/Workflow thing is hardly new. And note that
talking about Workflow doesn't actually solve the problem. You will still need to write some
sort of complex request dispatching logic which examines an incoming request and selects the
best workflow to execute. This is why so many MVC frameworks (like Struts...) fall down.
I've said it before and I'll say it again: the problem with MVC frameworks is that they are
frameworks. They impose way too many constraints on developers or they inevitably work their
way down into business code. Developers inevitably chafe under constraint X or they don't
like API Y so they run off and invent their own framework. It's a vicious cycle really.
Now, I didn't invent MVC, but I've used it a great deal (particularly doing Swing
development), and I believe the real value-add of MVC is it's ability to let you 'wire'
together complex components. (Events are also very important.) This is what the goal of any
servlet-side MVC 'framework' should do. It should basically just be glue that can be quickly
smeared onto your real object-oriented API. IMO, just having an 'Action' interface is
probably a bad idea. Nobody knows what actions are (are they business logic? Then maybe they
shouldn't be tied to the Servlet API. Or are they just sophisticated controllers that
forward to 'real' business objects?) and I've never seen a business process where 'Action'
was a first class concept. Note that in your own system, the card catalog, the Action
concept isn't there. I see Cards, a Card Catalog, and possibly a transactional data source
(though really that's an implementation detail) but I hardly see something you would call an
'Action'.
I'll just conclude the rant by saying that sometimes if something is difficult you just
shouldn't do it. I see people tearing through different frameworks without ever once
stopping to ask themselves why. Maybe the problem that shouldn't be solved. Personally, I
wouldn't put too much money on any sort of 'servlet application framework'.
Not Exactly Enlightening
2003-12-13 06:49:52 ljnelson [Reply | View]
While I don't think the article was silly, I agree with you in many respects. I'm glad N.
wrote it however; it's an articulate look at the frustration that drives us web developer
types to romp off into the woods and do our own frameworks and middleware.
What's interesting about the whole HTTP/HTML paradigm is how it forces you to deal with
events. Swing and other GUI frameworks are often written in terms of reacting to events, but
for some reason when we are confronted by web applications we prefer to think in terms of
workflow, or scripted actions. I wonder, honestly, why that is? That is, if we took the same
web application and turned it into a desktop application, we would have no problem writing
code to react to button events, focus changes, etc. Can't these concepts be reused in a web
setting?
Cheers,
Laird
Not Exactly Enlightening
2004-01-02 03:33:09 aurelioj [Reply | View]
While I'm definitely not an expert on Struts, I gave it a chance at first but, after
reviewing in depth the alternative Apache Tapestry framework, I found it that exactly
matches what you say: the web programming model used by Tapestry is almost the same you
would found in any desktop based application: UI web objects linked by mundane event
handlers, that's all.
In fact I don't think that the web programming model has to be so different after all...
Where the rubber meets the road
2003-12-12 11:54:48 skidancer [Reply | View]
This sounds very nice, but do you have a reference implementation ?
Excellent article.
Where the rubber meets the road
2003-12-16 07:53:48 jt2190 [Reply | View]
http://shocks.codehaus.org/
good start
2003-12-12 08:15:03 macinfinity [Reply | View]
I think the idea of orchestrating the workflow is a big improvement to what we have today.
My only concern is that you have greatly improved the model layer of MVC, but perhaps we
need a similar triad of roles for the view? I think to trivialize the view as just another
datasource will lead to system designs that only focus on data and not system behavior.
Maybe I'm wrong. I like the direction you are taking with this.
Good job!
Nicely ambitious
2003-12-12 07:17:42 ljnelson [Reply | View]
Well-written article.
I find it helps to think of web applications less in terms of page flow, which will lead you
into the workflow swamp, than in terms of applications whose UIs are trying to accomplish
common desktop tasks using suboptimal widgets.
For example, a typical login sequence on a web application could certainly be implemented in
terms of a page- or workflow--e.g. remember where the user was trying to go, make him log
in, possibly route him in a circular flow until he gets his password right, then point him
where he was trying to go in the first place--but this is much more clunky than thinking of
it as a perfect spot for a dialog box, if the web could only do dialog boxes correclty (user
tries to accomplish function X, but we need to pop up a dialog box to authenticate him
before we allow function X to continue). Dialog boxes and other components on desktop
applications that appear over the main application strike me as places where MVC might be
applicable--framed this way, our task would be to figure out how to implement these sorts of
desktop UI metaphors on top of the limited capabilities of HTML.
Ignoring the bizarre fascination they have with Swing for a moment, I like the ideas behind
the echo web framework.
Cheers,
Laird
Some thoughts so far
2003-12-12 04:04:40 prpatel [Reply | View]
Another Web Framework - Shocks
Unit tests are on the way
2003-12-12 07:38:50 n_alex [Reply | View]
I had dreams about Unit tests last night. Believe me--they're on the way. I focused all of
my effort in the first couple of months of serious development on just achieving the bare
bones functionality, so I could use the framework in developing a new JMX console for MX4J &
Geronimo and get these articles published. Now that the bare bones functionality is there,
I'm agressively writing unit tests.
And I'm absolutely open to refactoring the design. I'm looking at PicoContainer, AspectWerkz
and Drools at the moment.
great work
2003-12-11 10:30:24 joshy [Reply | View]
This was a very enjoyable read. I've seen some very good and very horrible MVC systems, and
I agree that they simply falldown when taken out of the context of user interfaces. I'm
really looking forward to the next one in the series.
--
[20B
[1;31m�� ��Դ:�������ʵBBS http://bbs.tju.edu.cn [FROM: 202.113.13.188][m
Technical Details
Message-ID:
<4DTbfT$AOM@bbs.tju.edu.cn>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!fr.ip.ndsoftware.net!news.moat.net!ctu-peer!news.nctu.edu.tw!netnews.csie.nctu.edu.tw!maily.cic.tsinghua.edu.cn!news2.happynet.org!TJUBBSShow Full Headers
Complete Article Headers
X-Google-Thread: f6cb0,d8b261d32b7b8975,start
X-Google-Attributes: gidf6cb0,public
X-Google-Language: ENGLISH,GB
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!fr.ip.ndsoftware.net!news.moat.net!ctu-peer!news.nctu.edu.tw!netnews.csie.nctu.edu.tw!maily.cic.tsinghua.edu.cn!news2.happynet.org!TJUBBS
From: bigbug.bbs@bbs.tju.edu.cn.no.spam (���|{�����ɱ�})
Newsgroups: cn.bbs.comp.lang.java
Subject: Beyond MVC: A New Look at the Servlet Infrastructure---zt
Date: 03 Aug 2004 07:54:59 GMT
Organization: �����ʵBBSվ
Message-ID: <4DTbfT$AOM@bbs.tju.edu.cn>
Mime-Version: 1.0
Content-Type: text/plain; charset="gb2312"
Content-Transfer-Encoding: 8bit
X-Filename: Java/M.1091519693.A