A Funny Java Flavoured Look at the World

Saturday, June 17, 2006

Action Class Design Guidelines

We were investigating an OutOfMemoryException this week and as usual the way I investigate such things is to whack them in google and then pick out the useful websites. This is usually a decent method and solves a lot of problems. The problem that occurred to me is that it does take a bit of thinking and problem solving skills out of the loop.

If I had thought about it a bit more I would of perhaps thought (but then again maybe not) where should I look, rather than just typing the problem into google and then following the links that might help you. I suppose when the links on google don't work you then have to use your brain a bit and then think about where you should look. In this case I had been advised by Billy Bob Bain who replied to a blog entry of OutOfMemoryException

I think I would have thought about it and headed off in that direction, if google hadn't made me so lazy.

Of course there is the other side of the argument which is that googling things can take you down very interesting paths and often you will get very useful information, very quickly.

Back to the programming in Struts, firstly I was quite shocked and a tad embarrassed I had never read the Struts user guide but better late than never. This section was interesting about designing Action classes especially the part about using only local variables and not instance variables. The research we had done actually showed us this although it took a while for us to understand the logging and what it meant.

I agree with the part that all the business logic should be taken out of the Action Class. My view on action classes is that they should be just an access point into your business logic code and they should pass on some relevant variable information and then retrieve and pass back the results. Currently we have a few classes where some of the business logic is mixed in the action class. Although in some cases there isn't actually much code in there, I don't think this matters because it means that we can't use any of the code in their again.

Having business logic inside the Action Class is also a bit like some old school JSP's which had html and scriplets all mixed, I think most people consider this a bad idea these days and don't do it, this is the same thought I have with the Action Class code. It also makes it very difficult/impossible to test the code and write unit tests for it.

Finally it means that your business logic code is held prisoner by the Struts framework, so what happens if you want to change frameworks in the future, a lot of messy rewriting and copying across.

I like the error catching remark, not many developers probably write software which takes credit cards but it would certainly make you think twice if you just entered your details to then be confronted with a stack trace error message.

Here is a link to the webpage where this data was taken from Struts User Guide and below is a quote from the document, below is the bit I found most interesting

4.4.1 Action Class Design Guidelines

Remember the following design guidelines when coding Action classes:

  • Write code for a multi-threaded environment - Our controller servlet creates only one instance of your Action class, and uses this one instance to service all requests. Thus, you need to write thread-safe Action classes. Follow the same guidelines you would use to write thread-safe Servlets. Here are two general guidelines that will help you write scalable, thread-safe Action classes:
    • Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class. Local variables are created on a stack that is assigned (by your JVM) to each request thread, so there is no need to worry about sharing them. An Action can be factored into several local methods, so long as all variables needed are passed as method parameters. This assures thread safety, as the JVM handles such variables internally using the call stack which is associated with a single Thread.
    • Conserve Resources - As a general rule, allocating scarce resources and keeping them across requests from the same user (in the user's session) can cause scalability problems. For example, if your application uses JDBC and you allocate a separate JDBC connection for every user, you are probably going to run in some scalability issues when your site suddenly shows up on Slashdot. You should strive to use pools and release resources (such as database connections) prior to forwarding control to the appropriate View component -- even if a bean method you have called throws an exception.
  • Don't throw it, catch it! - Ever used a commercial website only to have a stack trace or exception thrown in your face after you've already typed in your credit card number and clicked the purchase button? Let's just say it doesn't inspire confidence. Now is your chance to deal with these application errors - in the Action class. If your application specific code throws expections you should catch these exceptions in your Action class, log them in your application's log (servlet.log("Error message", exception)) and return the appropriate ActionForward.
It is wise to avoid creating lengthy and complex Action classes. If you start to embed too much logic in the Action class itself, you will begin to find the Action class hard to understand, maintain, and impossible to reuse. Rather than creating overly complex Action classes, it is generally a good practice to move most of the persistence, and "business logic" to a separate application layer. When an Action class becomes lengthy and procedural, it may be a good time to refactor your application architecture and move some of this logic to another conceptual layer; otherwise, you may be left with an inflexible application which can only be accessed in a web-application environment. The framework should be viewed as simply the foundation for implementing MVC in your applications. Struts Action Framework provides a useful control layer, but it is not a fully featured platform for building MVC applications, soup to nuts.


Post a Comment

<< Home