Friday, October 16, 2009

When To Generate Code

Code generation can be a blessing, a complete nightmare, or a combination of both for developers. It is a blessing when the right tools and the right know-how are employed. It is a nightmare when the wrong tool is used and much time has been vested in it. It is both a blessing and a nightmare when all appears to be going well until the maintenance of the code become unmanageable.

The whole point of using code generation in the first place is to eliminate the need for developers having to write mundane, boiler-plate code. Another use, although still considered boiler-plate in most circumstances, is generating GUI code. Many GUI builder tools allow for this in many programming languages.

Whether the boiler-plate code was generated by a UML modeling tool or by a GUI builder tool, the generated code should be imported by some other application module. This is necessary in order to promote isolation between the generate code and the human-designed code. The hand-crafted stuff created by a human developer usually doesn't interact well with the generated stuff. It is always going to make more sense to let the developer find a way to make the generated code work with the other application code. The reverse isn't true; the generated code isn't smart enough to work with the developer code.

So the use case for code generation is quite obvious; to save development time. In the case of developing user interface code, it is nearly impossible to maintain due to the level of verbosity. This is necessary and there really isn't any way around it other than to maintain the user interface graphically with a design tool that generates the code. So always generate GUI code, but always import it.

The classes associated with the problem domain generally store data and don't much behavior if any. These classes are good candidates for code generation. The reason being that the lack of behavior is a good thing when it comes to behavior. This is because the code that is being generated is a static artifact and the code it contains should be mostly conceptually static. Attempting to implement behavior inside a model that is then transformed into running code is a bad idea because method signatures aren't trivial to maintain and because behavior generally grows more complex.