Enforcing Strict Model-View Separation in Template Engines 2008-03-23

This is a great article on the importance of a clean separation of models and views (see Model-View-Controller).

More people are getting exposed to MVC with web applications programming, but not everyone are making it a clean separation. Much of the benefit of MVC comes from making sure all logic is truly isolated. The article - an interview with Terence Parr, creator of ANTLR and the StringTemplate library - is interesting, but it's the paper referenced at the end of the article that really makes it worth it: "Enforcing Strict Model-View Separation in Template Engines"

I must admit I have sinned in this respect too and relaxed separation more than I should. It is extremely tempting to relax the rules and do what amounts to computation of business rules in the view. The sins may seem small - it's only a matter of encoding some minor rule here and there. But it adds up, and before you know if you need to change a rule and are chasing all over the place.

My first major web app, a Webmail application that we scaled to about 1.7 million accounts back in 99/00, used strict separation, very much in keeping with Terence Parr's points. I built a template engine that specifically only allowed variable substitution, list iteration/expansion, and simple if/else with boolean values. It was a design choice, and one that was constantly fought by the engineering team, probably in part because I was not good enough at explaining the value. At the end of our use of the system (before we sold off the e-mail system) a couple of the guys even made a version that allowed them to embed Perl in the templates, completely circumventing the design goals.

Later, I've used more powerful solutions such as XSL templates, with part of the intent being that a lot of the bad logic is incredibly hard to do in XSL, so (the theory went) people would hopefully avoid doing it and handle the logic in the model where it belonged (though the separation in the code might have been ugly and badly managed). It didn't work. The templates grew incredibly complex because people insisted on trying to shoehorn logic into the templates that didn't belong there.

Terence Parr's notion of a separate "Renderer" layer - in StringTemplate's case using toString() to contain logic relating to the formatting of a single attribute - is interesting, and would likely have done a lot to clean that code up. He also has a good solution to the one value - multiple renderings problem: Wrap the objects in objects handling the rendering.

I'll certainly take a close look at StringTemplate and see whether it's reasonable to make a Ruby-ish version.

blog comments powered by Disqus