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. |
- Re: [MVC-Programmers] Model 3 Taylor Cowan
- Re: [MVC-Programmers] Model 3 Jeff Duska