I’m starting to wonder if code generation is a very subtle code smell. Something is nagging that I can’t fully express yet. I’m talking specifically about ‘active’ code generation – the stuff that is regenerated every build (and therefore cannot be hand-modified). It seems that rafts of complexity tend to accrete around the edges of the generated code, as behaviour that wants to be inside the generated classes (but can’t) gets deposited just outside the boundaries. This can lead to the accumulation of static utility classes simply to contain the behaviour that ought to be inside the generated code.
How to address this? Wrapping the generated classes inside hand-written decorator style classes is probably the quickest win. Make sure that all the references to the generated code are isolated from the rest of the system, which should help prevent duplication of the utility code by giving it a well defined place to live.
Code generation is a power tool, like a chainsaw. Just as a chainsaw in the hands of an ice-sculptor can be used to produce breathtaking works of art, it could do an unskilled operator like me a nasty injury. Treat power tools with respect, and know when to use them.
Code generation is evil except under the following conditions:
– If you don’t ever get to see the code that is generated (e.g. if the code is generated so that you don’t have to use a dynamic proxy to do something but it’s all handled by the container a la JBOSS i believe).
– If it’s a once off, e.g. new file generation from templates in an IDE.
otherwise, it’s the debbil. You can always write code that does the same job as the generated code in a more sensible, object oriented way that doesn’t leave 7000 redundant class files lying around. Included in my Code Generation is EVIL are the following examples:
– er… dang, ran out of more stuff, but it’s out there and it’s just plain wrong…
We’ve run into this in Roller, which used to generate the DAOs. This worked nicely in the beginning, but as the system got more complicated it just got in the way (also interfered with “optimizing” some relationships). We’re still using XDoclet to generate Castor’s mapping.xml though 😉
I tend to make the generated classes look for a potential abstract parent with whatever custom behavior I need. If the parent exists, the generated class subclasses it. This seems fairly straightforward to me and takes care of the customization needs that every code generation system encounters.
My response at.
I agree with Chris Winters. I use Castor to generate Java classes out of an XML schema, just like JAXB. The generated classes all extend a base class where I have some custom behavior. It works great, and is not a smell in my code, since it elegantly solves a problem that would be much harder to solve without code generation.