By Peter Bell

A Generalized Approach to Application Generation

At its simplest, application generation is the use of metadata to create artifacts (scripts, config files, layouts, database schemas, documentation, etc.). Generating applications isn’t particularly hard. Coming up with appropriately elegant, terse, comprehensible yet flexible grammar to describe your meta-objects is extremely difficult. This post is just a quick overview of the approach I’m using for coming up with an updated metabase grammar/schema and turning that into a working generator . . .

One More Time
The first point to note is that this is typically a painfully iterative process. Some parts of my meta model are starting to fit together, but many other still have ugly edges and jutting corners even though I’ve been refining the grammar on and off for a number of years. If writing an application is like writing an article, writing a generator is like writing poetry – there seems to be much less to show for it, it has a much bigger impact “per word”, and it (usually) takes an awful lot longer to write a 50 word poem than to write 50 words of prose.

The General Approach
The general approach to writing an application generator is pretty simple. Firstly you write a specific application that it should be able to generate. You then either use dynamic programming (parameterized base classes and the like) or simple templates and generators to try to use the same code base to solve other problems within the same class of problems. In my experience it can take anything from 3-10 custom projects to get a really good handle on the range of variability required.

The Benefit of Base Classes
I wrote an entire article about this for FAQU 2, but base classes allow you to investigate patterns of variability between your applications which is the heart of writing an application generator. You can then use their API as a grammar and their code as a template for creating your application generator if you decide for performance or other reasons that you actually need to generate your scripts.

Metaprogramming – Either Way
While this entire blog is nominally about application generation, in practice I don’t make a big distinction between dynamic programming (writing generic code that takes parameters to solve a wide range of different problems) and application generation (writing templates which use the same parameters but generate a set of application specific scripts). In practice, I find that dynamic programming is a little more flexible and maintainable (you don’t need to modify your generation infrastructure as the grammar evolves) so it is usually best to prototype using dynamic programming and then just move to generation for any elements of the application that need to be generated.

When To Generate
Once your grammar is starting to settle down, you may look to generate some elements of your dynamic code for a number of reasons. One might be Intellectual Property (you don’t want to give away a generalized solution – only a generated solution to specific problem). Another is language features, not all of which are available using dynamic programming. For example, my dynamic DAO doesn’t use cfqueryparams. I have pretty good input parsing using Regex’s, but I’m probably going to have to generate my DAOs to get the level of security I’d like from my application. Comprehensibility of the code and performance of the application are two other common reasons to consider generating code.

How to Generate
Brian Rinaldi has a great code generator, and I’ll be re-releasing CF Template later this month, but the mechanics of generating the artifacts from a templating language plus a grammar are fairly straightforward. One thing that can be helpful is to document your meta-model and list all of your artifacts and then look for patterns in the relationships between your metadata and your artifacts. Last time round I wrote a completely database driven generator which would look through the “generator” table, creating 1..n artifacts per record using the template, metadata description and any iterator specified along with the file name(s) for automatically naming and saving the artifacts. I really need to refactor this to make it much more OO, but I’ll post some ideas on this over the holidays as I start to play with it again.

In Conclusion
So, to summarize, start with dynamic programming using base classes. It’s much easier to refactor than a generator. As your interfaces start to gel, document your object model, your classes of artifacts and perhaps write a set of simple scripts for manually generating each class of artifact. As you start to see patterns emerging in the individual generator methods, you can then work up an orchestration layer so you can get rid of the specific generators and describe your generators using metadata as well.

Related Blog Entries

Comments
BlogCFC was created by Raymond Camden. This blog is running version 5.005.