Thursday, 28 August 2008

Code Generation

Tools are always great when they help build software faster and cleaner. Code generation can be great, if used well.

The 2 different times that I think that code generation is good is:
1) generate the code as a framework to save typing. This gets checked into your project and follows the same rules for naming, style, documentation, and coverage as if a developer wrote it. If the code needs to be "tweaked", that's cool. It should never be re-generated.

2) code that is generated as part of your build. This is generated every build. This code isn't checked in, it should never be tweaked. If you have to, then you'll either have to wrap those classes, use a factory, subclass them. Just no tweaking.

There is a 3rd way. An evil and broken path to go down. It's a hybrid of the other 2. It's when you have to occasionally regenerate the code and then tweak it to get it to work. Manually tweaking it, over and over again. Evil. This technique is to be hunted down and exterminated like code without tests.

3 comments:

  1. Just playing devils advocate here. Couldn't you use the third evil method if you used a nice diff tool to transfer over the manual tweaks, while stil being able to regenerate code. Then, let's say you were generating objects to map to you database. Well, you could regenerate the code, to bring in properties for new fields, and any old properties for pre-existing fields, which may have already been tweaked, could remain intact. Only the new fields would be brought in.

    ReplyDelete
  2. Are you taking about having an automated diff merge or have to do that by hand?
    If it's automated it might not be too bad unless you change your code generator version / settings / options that would break the merge.
    If it's a perfect merge tool, really you're just talking about a 2 step code generator.
    If it's manual and the person has to decide what are old fields that need to be moved over and what are new ones from the generation, that seems likely to fail to me.
    For your example where it's generating fields: instead of changing the object that's being used you could just extend it and put any custom fields / behaviour there. You'd be free to regenerate the class.
    I'm just bitching about manual steps. If it's manual, then it can be forgotten / skipped / done in the wrong order / generally messed up. It *can* be done, it's just the risk is much higher.

    ReplyDelete
  3. I'm not sure of the specifics, as I don't actually do this in real life. I was just trying to come up with a situation where one might want autogenerated code that could also be tweaked.
    I understand your problem with the manual part. But almost all coding is manual. So somebody would just have to take the same care with doing the manual diff on the automated code that they would if they were doing with any other kind of merge you'd encounter through general source control use (2 people editing the same file). Actually, I think this would be pretty much the same, except that one of the people doing the editing would be a computer.
    I like your idea of extending the object, and making the generator only generate an abstract class, with everything overrideable. That way you can still generate the base, and be completely safe knowing that anything you changed in the subclass would stay intact.

    ReplyDelete