Separation of UI, rules, and data

I’m honored that one of the reasons why companies contract with me and Nebula R&D is because they want well organized code, not just functional code. Almost anyone can write functional code, that’s an exercise with syntax and debugging. A company tends to have more appreciation for code that’s truly "designed", not just "written", only after they’ve paid a lot to re-write existing code to do something just a little different. I’ve written a number of forum postings on Model-View-Controller (MVC) code organization, but nothing yet for the blog here – until now.

This post was written in response to a recent U2 Forum request about using Java Server Faces with or without Ajax, and connection into Universe without RedBack. I rarely post Java code but the lessons here apply to all languages. Also, this isn’t about JSF or Universe or Redback per-se, and that’s the point because we are talking about separation of tiers, and any front-end, middle-tier, or back-end components can be substituted here.

If you’re using MVC techniques properly, where the UI, business objects, and data integration layers are abstracted from one-another, then it doesn’t matter if you’re using JSF or Struts, with or without Ajax, etc..

For example:

FacesContext context = event.getFacesContext();
HttpServletResponse response =
   MyGetResponseMethod(context);
HttpServletRequest request =
   MyGetRequestMethod(context);
String userdata1 = request.getParameter("userparam1");

Now you have data, and it doesn’t matter if it came from JSF, Struts, or any other Java code – and except for the FacesContext and Servlet class references, C# people might think that’s C# and not Java.

String myresult = GetMyResult(userdata1,…);

The return value can be a single value, array, whatever. All that matters is that GetMyResults returns some data. Again, this is completely abstracted from the UI. After a result is available:

StringBuffer out = MyBuildAjaxResult(myresult);
try { MyResponseWriter(out); }
catch (IOException ex) { MyErrorHandler(ex); }

So that’s the JSF/Ajax interface. The GetMyResult function should operate on an object which represents a business rule.:

String GetMyResult(datavalue,..other inputs..) {
     String custKey = datavalue;
     Customer cust = new Customer(custKey);
     String custName = cust.GetName();
     return custName;
}

Note that there is no data access here. At this point everyone has their own sense of elegance about where the data access is actually done ( and a lot of people just throw everything into the UI which is a big mistake ). In true MVC form the customer class itself shouldn’t connect to the database, it should call some data access layer that makes the connection:

// Customer class
String myName = "";
public Customer(String key) { // constructor
    MyDataAccess datasource =
        new MyDataAccess(some_session_data);
    String[] custData = 
     datasource.GetRecord(
      "customer",key,some_session_data);
    myName = custData[0];
    myKey = key;
    myBlah = custData[some_element];
    return this;
}

Finally, the MyDataAccess class does the mechanical labor of connecting, disconnecting, state management, whatever. You can use UOJ, RedBack, or yes, even mv.NET which has session pooling and costs less than RedBack. 🙂 Be sure to use lots of try/catch blocks to trap all of the communications errors that might come up – there’s nothing more useless to a user than telling them some embedded data access instance just threw an unhandled exception type.

With this architecture you can replace the back-end database or any of the connectivity pieces without disturbing your UI or how the UI gets data from business objects. You can modify the customer business object to get data from some other database, or you can change it to use web services or remoting – all without no changes to any other component. Any of these components can be re-used in other applications, even those that use different client or server technologies.

Leave a Reply