A few weeks ago I had an interesting exchange with a friend of mine concerning code generation. This post echoes some of the thoughts and perhaps reservations that I have towards the practice.
So what exactly do I mean by the term code generation? Code generation is the practice whereby a tool or a script generates source code from templates as opposed to typing the code by hand. One example would be of a script that examines the columns in a table and creates a stored procedure. A more extreme case would be an MDA/MCD tool like Visual Paradigm.
Learning the hard way
A few months ago I was tasked with developing a large application for one of my clients that made use of extensive model taxonomies that also required a management interface.
With a good ORM and some thought behind the persistence mechanism, we were able to leverage a lot of reusable code that gave us a unified, DRY approach to persistence, validation, search queries, caching, lazy row-fetching and transactional operations. Only one daunting task remained and that was the UI. Again, we did our due diligence and came up with some useful generic base classes for Save/Update/List views but even so, the amount of fields on each Save/Update view was staggering and it was incredibly time-consuming to add them all. At some point when I had done about 10% of the work, I started realizing how genuinely tedious the task was. Integers would always be rendered as asp:TextBox accompanied by an asp:RegularExpressionValidator, one-to-many relationships would use a select-box or auto-complete widget and so forth and so on.
Knowing that my models’ members were lush with juicy meta data defined via attributes, I decided to use introspection to generate the code for the views. It took me about 2 weeks to write an IronPython script that could make sense of all the various types, validation attributes and implicit rules in my DLL. Once I had that, the rest was pretty easy. A single command would spit out thousands of lines of HTML and C#, but it still required modifications here and there since there were spots of non-standard behavior.
We now we have some 60 views that contain a lot of tedious code. As soon as something changes in our model, we still have to update the templates to reflect new validation rules or object definitions. It’s not as simple as re-generating the views because that would overwrite changes that have been made. I’m not ashamed of the quality of the code - with the abstractions that are already there its far exceeding the level of quality that you would expect from our average .NET developer. What bothers me is the sheer size and complexity which threatens to turn this code into an unmaintainable mess and a recipe for failure in the long run.
What went wrong? For starters, the problem wasn’t how to create hundreds of lines of HTML in each view – the appropriate question was why. To use a common anology – I was curing the symptom, not the disease. The real problem I was trying to solve was the severe GUI/Model impedance mismatch in my web-framework, ASP.NET. Had I been brave enough then I could just have used those two weeks wrangling with ViewState to come up with a well thought out, Reflection-based Form abstraction like the one found in Django.
Conclusion
In many instances code generation is an appropriate solution to a repetitive task, but first you have to ask yourself why you want to use it. If it’s solving a time-consuming, reoccurring task of low complexity then go ahead and use it, but implore yourself to look beyond the immediate problem at hand. You will be surprised to find out that frequently, the problems you are trying to solve are far more systemic and can be solved more elegantly by adopting a useful abstraction instead.
Code-generation can be a divisive and destructive approach to programming when applied systematically in a development environment or development methodology. Programming should not be viewed as a necessary evil as this fosters the wrong mind-set. It tends to put developers in two camps – one that knows how to solve problems and one that just knows a tool - most people who interview and hire programmers can attest to this.