Showing posts with label Frameworks. Show all posts
Showing posts with label Frameworks. Show all posts

Saturday, December 4, 2010

Why I will Never Use Spring Tag Libraries in my HTML

The Facts - Web Design and Web Development Involve Completely Different Skills


I work with a team of developers and a team of designers. The designers I work with know Photoshop like they know the back of their hand. They are experts in writing clean, standards based, cross browser compatible HTML and CSS. They design and produce high-quality, beautiful, $15k websites for our clients. Their code validates with W3C validators. The results are amazing.

Our web developers know Java. They can pound away at any server-side problem and produce a solution. They use Struts, Spring, Restlets, JSP, JSTL, Velocity, they can configure Jetty and Tomcat, and they can look at log files and solve problems.

However, if you give them an HTML document, they'll give it such a severe beating that it becomes unrecognizable by it's original creators.

The beautiful HTML turns into a 3 headed monster with unclosed tags, numerous validation errors, and no IE support. The developers struggle for days with guesswork of adding a tag here, removing a tag there, editing a CSS rule here, and who knows what else there.

Of course, the designers are unable to help because of the code soup that results from mixing JavaScript, Java, and HTML into a JSP page.

The resulting web application looks great on the outside, but under the hood it's an absolute nightmare! Ask the designers to go back in and make a design update, and their faces go blank. A 4 hour change takes weeks! The developers can't make the changes because they barely got the HTML integrated with the backend system.

So developers and designers sit side by side trying to understand all of the complexity. The designers can't determine what the application is doing with the HTML, and the developer can't understand what modifications to make to the HTML. Logic mixed in with the HTML is of course overwhelming and makes the code completely unmaintainable.

In summary, designers and developers just plain have different skill sets, at least at my company, and it's foolish of us to think that designers and developers can use the same tools. People do better at what they specialize in, and to try to force that change is wasted energy.

How do I know this, you ask? Because I've fought this fight for years and have continued to lose miserably. "Eclipse is a software development tool, not a design tool", they tell me, "and we're not using it". End of discussion.

Of course, I have convinced a designer or two to try it out. In the end it just slowed both them and me down because Eclipse would inevitably break, and I would end up having to help fix it. Afterwards, we both silently agreed it was a bad idea. The designer stopped using it, and I stopped asking questions.


Light at the end of the tunnel - Keep Content and Behavior Separate



Recently, I took on the project of testing out a new Google App Engine feature and put together a prototype of Google's new ChannelAPI using Google App Engine SDK 1.4.0. Since we have chat designs, I used this as an opportunity to experiment with some new ideas regarding HTML integration with a J2EE application. Below are the details:

  • The HTML exists as a static HTML page. My rule for this experiment is no JSP pages!

  • I use JQuery to bind all my click event handlers dynamically, which leaves my HTML free of pockmarks and other markup that would bind it to the framework.

  • Chat applications involve inserting data in a message window. I used the concepts of manual templating to inject the messages dynamically, without mixing HTML and JavaScript. I'll describe more on this below.

  • My application sends messages to the server using AJAX. Calls to the server are made through the bound click event handlers. No tag libraries! Only client-side code!



I've observed designers over the years, and I've also observed developers. Our designers put placeholders in the HTML they create to mark where the dynamic content would go. The pages can be loaded as static files, and look just like the final result except the fake data. Below is an example of the body of an HTML file, with the placeholder in bold:

<body>
   <input type="text" name="alias" value="James" />
   <button id="join" value="Join Room!">Join room!</button>
   <button id="leave" value="Leave Room!">Leave room!</button>
   <button id="test" value="Test Message receive!">Receive Test Msg!</button>
   <div id="messages">
      <div class="message">
          <div>
              <span class="name"></span>
              <span class="timestamp"></span>
          </div>
          <div class="text"></div>
      </div>

   </div>
   <textarea id="messageBox"></textarea>
   <button id="sendBtn" value="Send">Send</button>
</body>

Now, my development team would normally be tempted to solve this problem by pulling out the bold HTML and placing it in the JavaScript callback method as follows:

// create the div for the message
var message = "<div class='message'><div><span class='name'>"+name+"</span><span class='timestamp'>"+timestamp+"</span></div><div class='text'>"+message+"</div></div>";

// inject the div onto the page
document.getElementById("messages").innerHTML += message;


When our designer needs to add a new feature to the chat application, he'll have to study the HTML that's inside the JavaScript to figure out where to make the changes. Instead of focusing on his area of expertise, the front-end, he'll have to become an expert on the actual application's inner workings. He'll need to understand Comet, JavaScript, and how the application works. As you can imagine, this is an extremely inefficient use of his time.

A better approach would be to use a templating engine, such as Velocity or Freemarker:

      <div class="message">
          <div>
              <span class="name">${NAME}</span>
              <span class="timestamp">${TIMESTAMP}</span>
          </div>
          <div class="text">${MESSAGE}</div>
      </div>

This is better, but it's still based on old ideas that still suffer from the same problems. I can't give a JSP file to a designer who knows nothing about Spring, Tomcat, Jetty, Eclipse, JavaBeans, and other technologies that bind the document to the framework. In addition, even if he did understand these technologies, he doesn't have 4 hours to spare to setup his development environment for just a 2 hour change. Even with templating, the files can't really be loaded outside of the JVM and outside the context of the framework.

Velocity and Freemarker are marketing ideas that in practice are failures. Anything that involves a developer mixing non-HTML markup with HTML will create more problems than it solves.

Instead, I took the approach of leaving the fake, empty HTML-valid message in the HTML and using it as the actual template:

var template;
$(document).ready( function() {
chat_template_read_only = $('.message'); // store the original template from the HTML (in bold) for later use.
};

Now, in my callback method, I do the following:

// make a copy from the template I saved earlier
var message = chat_template_read_only.clone();

// now use JQuery DOM methods to inject the content in the appropriate places in the copy.
message.find('.name').html(name);
message.find('.timestamp').html(timestamp);
message.find('.text').html(text);

// dynamically inject the new message into the HTML.
$('#messages').append(message);


Here you can see I'm accomplishing the same goal. I'm placing the dynamic content in an HTML block and injecting it into the DOM. Now, if in 6 months the design team needs to add a department header and maybe a response time to each chat, we can give them the current, live, HTML file and they can load it outside the context of the web framework, code their changes, and then send it back to the development team.

We can integrate new changes simply by making changes to the Jquery CSS selectors in the JavaScript files! There is no need for the web designers to understand anything about Eclipse, Java, Jetty, Tomcat, how to configure the application, or any of the applications inner workings.

Let me repeat that one more time: The HTML document is not bound to the framework and can be loaded outside the framework. It can be loaded from an Apache server, it can be loaded from the desktop by clicking on the file. It can be modified by the designers without needing to look at any Java, JSP, or JavaScript.


Spring Taglibraries



I was looking at Spring's JSTL tag, which is used to bind server-side data to an HTML form element so the form can be rendered with a session ID and any preloaded data from the server. The server-side tag generates an HTML form tag.

The benefit here is that web designers are supposed to be able to work with these tags, or at least that's what they say. In practice, in all my years of software development and programming, I have yet to ever see this magical unicorn walk out of the shadows and into the sunlight.

Where are these mystical organizations that operate in this manner? I'd like to meet one of these developers. Are they human? Do they eat and breathe like I do or are they just mere fiction?

This tag is useful in cases where a developer needs to pre-load the form with data from a persistent object. Although I'd love to just ask the developers not to use it anymore, but that's just as difficult as trying to set the web designers up with Eclipse! It just ain't gonna happen!

The problem with these templating languages and tag libraries is that they completely alienate the web designers while simultaneously encouraging the developers to trash the HTML. These frameworks make it impossible for designers to use their own tools. Although these templating engines claim their goal is to allow everyone to work together, they fall way short of the mark. These frameworks were obviously developed by programmers who have absolutely no clue about design.


JQuery Manual Templating



While looking at a <form:form> tag, I thought to myself: "Now wouldn't it be nice if I could use some tool on the server-side to bind my data to that form dynamically, without having to actually make any changes whatsoever to the actual HTML document, just like I did on the client side with JQuery?

Then it hit me! Java doesn't have anything like this that I know of, but since JQuery can run in server-side JavaScript, perhaps Rhino or Claypool is the answer! Imagine using JQuery to manipulate HTML documents on the server side without ever having to modify or template the code.

What I picture is a form of binding server-side tags dynamically. If we can use CSS selectors on the client side, why not create a method of doing so on the server side. I picture a solution such as this:

Import server-side JQuery into our JSP page:

<script type="extjs" src="server-side.js"><script>

// server-side.js
$('form').replace('form:form');
$('input').replace('form:input');


Now, instead of editing the HTML directly, we can bind our server side tags dynamically. When the designer needs to update the page, he can load it completely independent of the Spring environment, make modifications to it, and give the file back to the developer.

There is currently no solution out there for this, but I would greatly appreciate any advice from anyone who has ideas/suggestions for how to get this concept started!

Saturday, April 5, 2008

Model View Squared Controller

At my place of work, Model View Controller is a common architectural pattern used as the foundation for the applications that we develop and maintain. MVC is a common pattern that can be seen in just about any software industry, from Agile development shops to those that follow the more traditional models of development.

As Computer Scientists, we often look for ways to solve a problem not once, but for N cases. Some really smart people at the Apache Foundation and SpringSource have designed and implemented solutions for Java that lay the foundation or "framework" for quickly and efficiently starting the development of an MVC application.


MVC Framework Flow in Struts and Spring



With both Struts and Spring, a request is sent from a browser to a servlet container, such as Tomcat or Jetty. The container hands off the request to a servlet declared in an XML configuration file. The servlet processes the request and hands it off to a controller. The controller, typically an Action subclass in Struts or a Controller subclass in Spring, makes calls to the model to retrieve data from the data source, manipulate that data, and pass it back to the controller. Afterwards, the result is forwarded to the view. In Struts, an ActionForward is returned by calling the mapping.findForward method and passing in a String that maps to a JSP page declared in the configuration file. In Spring, a ModelAndView object is instantiated with the JSP filename as an argument.


Advantages and Disadvantages of Struts and Spring



This particular pattern is well-known for decoupling the business logic from the user interface, the user interface from the controller, and the controller from the business logic. The advantage is that the view can be modified, maintained, or completely replaced, independent of the rest of the system.

Well, almost....

If you want to change the view, it's still a development issue. You still have to deploy a new Web Application Archive, or WAR file for short. You still have to test the application, as other developmental changes could affect the behavior of the system.

Unless you break the application up into completely separate modules that all exist outside the application....

Velocity, a templating language developed by the Apache Foundation, is very similar to Java Server Pages (JSP), except the Velocity files can be hosted outside the WAR file, on a completely different server, completely independent of the application.


The Velocity Advantage



Picture an enterprise-level reporting tool designed to be hosted by an application service provider. Imagine that there are thousands of clients who use this system and who regularly depend on the functionality. If you're a project manager for this reporting tool and you want to allow all of your clients to customize and skin the user interface without needing to involve your developers, then you need the Velocity Advantage!



The JSP Disadvantages



Even with MVC, you may have a few JSP pages that create a tightly coupled system where a change to the HTML structure for one client will affect thousands, perhaps with disastrous results. While the number of pages is small, it may take a lot of work to make them all work together for each logical case.

On the other hand, you could have N JSP pages for N clients. This means that deploying a new feature means that you will need to modify N JSP pages.

No matter what solution you use, the fact remains that updating the user interface becomes a development issue that involves a complete development, testing, and deployment cycle, as well as the possibility of either introducing new bugs into the system or creating a situation where you require intense, time-consuming CVS management. Being organized takes time.

But using Velocity, these JSP page equivalents could be stored on the client's servers, or an external server that you maintain that is specifically dedicated to hosting these view components. Suppose you then have a configuration file where you can store the location of the view for each client, kind of like struts-config but better; it exists outside the WAR file! And suppose the client has control over which view they use!

Sure, with Struts and Spring, the configuration exists in an XML file outside of the codebase, but you still have to pack a new WAR file and possibly restart your servlet container when making changes to these files. This, of course, equates to downtime!

Here is where those smart people at the Apache Foundation failed to completely solve this problem. (For the record, the developers of Struts are extremely bright problem solvers who have made significant contributions to the development community. These contributions have reduced the cost of development significantly in many J2EE environments, and without them, I would probably still be sorting through a mess of code trying to figure out how to write a controller! Additionally, I've not seen a container/framework yet that solves this problem in the manner that I propose.) What's the point of externalizing all of my configuration if changing it still requires me to disrupt my production systems? Any changes made to web.xml, server.xml, struts-config.xml, tiles-defs.xml, or any other configuration file requires a servlet container restart, in most cases.

And this is exactly the type of problem that would make the above scenario fail with a framework such as Struts, or Spring, or WebWork, or Struts 2.


Model View Squared Controller



The framework can of course still be used, just not with the struts-config.XML file. To allow clients to modify their HTML or CSS or change the view that they see, they have to be able to access your own customized, instantly reloadable configuration schema, not the framework schema. You can use an XML file on your server or even a database, as long as changes to the data are instantly recognizable.

This is the type of framework that I want to develop. I'll call it Model View Squared Controller. It's too long though. I need a better name. The concept is that your view would consist of a single JSP page, but all it would do is output data from a bean or even the HttpServletRequest object. The bean would be populated in the controller with the view template retrieved from outside the application. The view would be created as a Velocity object, processed in the controller, and then forwarded to the JSP page.


Model View Squared Control Flow diagram
Essentially, there are two "views"; one is part of the application and the other plugs into this view. The JSP page within the WAR file does nothing except render the data, while the other view -- the plugged-in view -- is actually retrieved from a remote data source and assembled in the controller. It's almost as if your view becomes a piece of data. It actually is data!

It's a tough concept to ponder. "My view is data, you say? I thought the model was the data?". Well, it is. But the view just happens to be something that we retrieve from an external data source, whether it be a remote server as a file, or as a template stored in a database.

Forms can be data. I don't mean the data that is entered in the forms, I mean the forms themselves! In your reporting tool, clients want to be able to use different forms with different field names and values. If your developers are smart, they can design a database schema that is abstract and extensible, one where field names aren't column names, but pieces of data themselves.


Fitness Tracker



This is also the answer to my Senior Design project! I designed a system for allowing health club owners to add exercises to the system so that their members could record data for each exercise.

Since each exercise is different, there are different data fields for each type of exercise. These things can't be hard-coded because they are data. Not data that the member would see, but data that the client, the club owner or manager would see! Once again, the form fields are data!

Same with the reporting tool! Each client will have their own idea of what data they want their employees or customers to be able to enter. Therefore, you absolutely must solve the problem once and only once! Otherwise, you'll be scrambling to reinvent the wheel for each new customer that knocks on the door.

I'm going to continue to write more on this subject, as I feel that the concept of a model generated view, view view, or whatever I decide to call it, is oftentimes overlooked.
Google