Monday, 31 October 2011

Maintaining Separation of Concerns when using a JSP Front Strategy MVC Pattern.

My last MVC blog tried to add a little depth into exactly what the MVC pattern is in relation to web-applications, and in writing it I highlighted the problems and pitfalls of using a JSP Front Strategy as an MVC front controller pattern. To sum this up, although favoured by some organisations, it seems to me that using JSP Front Strategy makes it all too easy to mix the controller logic, view information together with the model in the wrong place, which results in nothing more than a plate of indecipherable spaghetti code.

So, I thought that I’d investigate a technique for implementing the JSP front strategy without creating a dog’s dinner and try to sort out a few rules that can be applied if you ever find yourself working on, what is after all, obsolete technology.

In my last MVC blog I also highlighted how frameworks such as Spring MVC approach the problem of maintaining the separation of concerns. Both patterns use a front controller; however, Spring uses its front controller to delegate the controller concerns for any given request to one of your Java classes: a sub-controller if you like. The UML Collaboration Diagram below takes a fairly simplistic, bird’s eye view of how this works.


From the diagram, you can see that the sequence of events runs something like this:
  1. The browser sends a request to the webapp, which is picked up by the front controller servlet.
  2. The front controller servlet calls some other classes to do things like validation and what not and then forwards the request to MyController
  3. We’re now in the code that we're responsible for writing, so MyController should be fairly well written in the usual N layer architecture, calling on one or more service classes that are responsible for doing some jiggery-pokery with business rules.
  4. The service class generally needs some data, so it makes one or more calls to the database via a DAO.
  5. The database access object duly returns the data to the service object.
  6. The server object messes about with the data, applies a couple of rules and adds it to a model object of some sort. The model object is then returned to the MyController.
  7. MyControllersorts out the next view and combines it to the model, passing control back to the front controller.
  8. The front controller looks at the view and grabs hold of the appropriate JSP. It sticks the model in the JSP’s page context returns the whole lot to the browser as HTML.

Now I know that this is simplistic and that the front controller is a collaboration of lots of classes cohesively working together and performing additional tasks such as validation, type conversion and more besides, but it demonstrates how separation of concerns is maintained and could serve as the basis for something similar using the JSP Front Strategy.



The diagram above shows that you can maintain separation of concerns using a JSP Front Strategy; however, it takes a little more self-discipline. The main difference is that I’ve replaced the MyController class with an instance of MyCustomTagLibrary. The events in this collaboration diagram run something like this:
  1. The browser sends a request to the webapp, which is picked up by the Front Controller Servlet.
  2. The Front Controller loads and run calls the appropriate JSP for this request.
  3. The JSP calls the doStartTag() of the MyCustomTagLibrary, which is where the code that you and I may have written takes over. Just because this is a custom tag library, there’s no reason why the same N layer architecture shouldn’t be used.
  4. MyCustomTagLibrary marshalls a few arguments and calls one or more service classes that are responsible for doing some jiggery-pokery with business rules.
  5. The service class generally needs some data, so it makes one or more calls to the database, via a DAO.
  6. The database access object duly returns the data to the service object.
  7. The server object messes about with the data, applies a couple of rules and add it to a model object of some sort. The model object is then returned to the MyCustomTagLibrary.
  8. MyCustomTagLibrary takes the model provided by the service object and stuffs it into the JSP’s page context for rendering.
  9. MyCustomTagLibrary then passes control back to the JSP, which uses the model to display the page.

I guess that in terms of a class diagram, you should end up with something that looks a little like this:


Again, this is a simplistic bird's eye view of the process and it does miss out a few crucial steps such as validation and type conversion, but does this approach work? Obviously yes, but as I said above it does need a bit more self discipline, so thinking along these lines, there a a few rules that could be applied (there are always rules in software development!)

Rules Rules Rules

  • Maintain separation of concerns. This is the key rule; don’t mix presentation code with business logic or database access.
  • Don’t write custom tags that produce HTML output, leave that to the JSP.
  • One custom tag per JSP. The first pattern presented uses one MyController per request, so it seems like a good idea to do the same with custom tags.
  • Never use Java Scriptlets in JSPs. Java Scriptlets are the spawn of the devil. They’re insidious bits of Java code that are just hacked into the wrong place. They’re very difficult to test as you can’t write a JUnit test for a JSP (so far as I know, please contact me if I’m wrong) and belong to the old programming paradigm of code, ship and forget it.

I appreciate that this is all opinion, but the very fact that I’m having to think of these rules demonstrates the flaw in the architecture: good architectural design means that it should be hard to make mistakes and when using the JSP Front strategy it’s all too easy to make mistakes.

Finally, I know that the title, Maintaining Separation of Concerns when using a JSP Front Strategy MVC Pattern could be snappier, so suggestions on a postcard please.

No comments: