For some time now J2EE developers have been familiar with what Sun
refers to as "Model 2", a pattern which separates the model, view, and
controller responsibilities into separate modules.  Struts encompasses
this pattern rather nicely and as a result has become a popular
framework for J2EE web tier applications.  Model 2 supports the three
basic roles within a  UPI and stops there.  The Model 3 architecture
adds pattern support for the interactions between MVC layers.  This
support includes:
1. An improved event model.
2. A new scope that encourages efficient memory usage.
3. Standardized create, read, update, and write support between model
and controller.
4. Supports cooperation and interaction between multiple MVC components
( portlets ).

Model 3 Events
Struts 4.0+ provides its actions with one simple event, "execute".  Many
action implementations are difficult to read because the program logic
is placed in the body of one method.  A common symptom are actions with
long and tedious if/then/else sections.  But when you a closer look at
what Struts actions do, you'll discover that they follow a common
pattern.  Struts actions prepare the model for reading, update the model
in focus, and traverse the model based on actions performed in the UI (
button clicks ).  Handling button clicks tends to cause the worst action
code.  Here again we see that there is similarity between most
applications.  The UI is normally sending the following requests to the
controller: update the model, delete part of the model, insert new data
into the model, or view a different piece of the model.

Event
Fired...
preActExec(Model3ActionEvent ae) before the execute event.
postActExec(Model3ActionEvent ae) after the execute event.
onDisplayExec(Model3ActionEvent ae) when user requests to view the model.
onSaveExec(Model3ActionEvent ae) when user requests to save changes to the model.
onNewExec(Model3ActionEvent ae) when user requests to insert into the model.
onDeleteExec(Model3ActionEvent ae) when user requests to delete from the model.
onCleanUp(Model3ActionEvent ae) when user moves to another action.

As a further feature, the BaseBeans model layer handles these events
while allowing the application Action classes to override the default
behavior.
Model 3 Session Management
Projects which commit to using struts may end up with serious problems
when developers don't understand the intricacies of keeping session
memory management.  The HttpSession is a wonderful tool, especially to
those of us who remember using cookies, hidden fields, and other tricks
to manage state over an HTTP session.  Need to carry some bit of data
between two views?  Put it in the session.  On  the other hand there are
the memory misers, always cautious not to put anything into the session
lest performance suffer due to lack of memory.  These two ends of the
session management spectrum are exacerbated in struts applications.  The
liberal approach to session memory usage will tend to work great in
development, however, when the system is put to the test memory usage
begins to add up and have a real affect on performance.  The
conservative approach to session memory management is even worse.  It
results in useless or redundant queries to the database.  Every time the
user requests a new URL, the action reloads the model, eating server
side network bandwidth and putting load on the database server.  Another
symptom is  a reluctance of the developer to "share" data, for example,
I've seen many actions which reload drop down list data each time the
action is invoked.  Imagine the useless waste of hitting a database
multiple times per user just to get a list of states or some other
rarely if ever changing list.  What project leaders must understand is
that while they may carry their session management ethics with them into
the the project, other developers may not have enough experience to know
how to keep the session clean while using it to their advantage when
called for.  The question that arises is...can something be done to
automate session clean up?  I'm happy to say that there certainly is.
We propose that there is actually a "hidden" scope in most applications.
  Currently there are 4 Scopes defined in the J2EE specification:
application, session, request, and page scope.  The hidden scope lies
between session and request.  In other words, it is often necessary to
share data that spans several requests, however, the same data isn't
needed for the duration of the session.  In keeping with struts, this
scope is called "action" scope and forms the basis for what we are
describing as "model 3".
Uncovering the 5th Scope
When used properly, the same action will interact with a user during a
business process.  A good heuristic I use when developing actions is to
combine all operations on the same data with a single action.  For
example, you might use the same action to create, read, update and
delete contact info.  The data being shared would be a perfect candidate
for our action scope.  This brings us to a problem that needs solving.
What determines the life span of the action scope?  A session begins
when a client first accesses the server and ends after a time-out period
of inactivity.  Obviously the action's scope should begin when a user
first visits the action, but how should it end?  Determining the end of
an action's scope requires that we apply some type of pseudo delimiter,
similar to the session time-out.  The simplest approach is to consider
ownership of the action scope as atomic, such that only one action is
"active" at a time, per user session of course.  As long as a user is
interacting with the current action, the current action scope remains
active until such time as the user visits a different action or when the
session times out.  This would cause all memory and resources of the
previous action's scope to be released and made available for garbage
collection.  In standard computer science fashion, this may be modeled
as a "token" sharing algorithm.  In practice many of us may have
duplicated this feature, perhaps many times over on different
applications, without recognizing that we were actually hinting at a 5th
scope.  But not to worry, we won't keep it hidden any longer.
Model 3 CRUD Support
Let's be honest, most of our applications create, read, update, or
delete data.  One of the frustrations with thin client applications is
that creating screens is difficult.  Problems that might have been
solved in an afternoon with Power Builder or Visual Basic can consume
days with JSP and Java.  The BaseBeans Model 3 architecture supports
CRUD with a common data model.  Our data model, JDAO, is based on a
simple cached data structure and therefore does not limit you to any
persistence layer.  By default JDAO utilizes JDBC, however, EJB, JDO, or
even webservices can be the data provider for a JDAO object.  The JDAO
simplifies the activities most commonly applied to a data model, namely,
  creating new rows, deleting rows, updating rows, and reading rows.
This model is extended to the struts form layer so that applications can
bind user interfaces to the data model within hours instead of days.
This allows projects to be up and running, creating data, reporting on
the data, and evaluating user interaction in a fraction of the time
expected for traditional web forms development.  JDAO supports
auto-increment columns as well as efficient deletion techniques.  It
allows for batched updates and connects to J2EE DataSources by simply
pointing it to the correct JNDI path.

There is now a project on SourceForge called Model3
(
http://sourceforge.net/projects/model3/) , you will be able to look at
this implementation as it evolves. In a few days we will make an initial
post.

T.C.

Reply via email to