The Dopefly Tech Blog

« The Dopefly Tech Blog Main page

Thoughts on code regeneration - patterns for customizing

posted under category: ColdFusion on November 24, 2009 at 12:00 am by Nathan

Since Mark Mandel gave his transfer presentation to the AZCFUG last June, I've been contemplating the different ways there are to work with and customize generated code, and especially re-generated code. Here are some patterns I have recognized. Please read and add your own in the comments.

Generic Scaffolding
Something I've said ColdFusion has needed for years, and we're still not there, standard scaffolding creates the model, view and controller on a single database table (not usually much more complicated than that). From there, you have to edit the HTML to make it match your UI, and edit everything else to do what you need it to do. It's rarely correct out of the box. When your database structure changes, you either have to regenerate and reapply your changes, or apply the DB changes to all of your layers by hand.

Styled Scaffolding
If your UI is clean, and the scaffolded UI code (the HTML) is as well, leave the output as is and just style it with CSS. Wrap your own layout around it and you're set. This only accounts for basic changes that you would make.

Transformed Scaffolding
To account for bigger changes, like changing form field types or turning a form into a wizard, you could try running a transformation on the scaffolded output. This works by making a tool that will change the original structure on command, for example string operations on code. It's doable, and I've done it. It works, in a pinch, but it tends to be more work than it is worth. If you end up physically injecting code into an object, there are better ways to go.

Extended Injected Stubs
Extend the generated code with your own objects (or inline includes for HTML). Replace calls to the generated code with calls to your code. It's kind of a make-or-fake-your-own-stub strategy.

Pre-generated Stubs
The Reactor ORM has a neat trick. Reactor generates stub classes that extended the framework's real generated classes. These empty stubs are placed in your playground to put in any code you want, while the tabe definition heavy lifting classes are saved inside Reactor's core file structure. Reactor can then manage the ORM while your stub files are safe. This strategy can work for you, too, except for the two big downsides that ultimately killed* Reactor: folders with potentially huge numbers of generated files and the unweildy nested object structure. CF 6 and 7 especially have trouble keeping performance with the inheritance tree, which, from memory, looks something like:

reactorObject
reactor.DataObject
reactor.DAO
reactor.myTableDAO
myTableDAO
myTableDAO_MSSQL
* No, it's not dead, but had a little bad press and it was hurt bad enough to end up on the outside.


injected Stubs
Mark Mandel's Transfer also generates files and saves them in the internal structure of the framework, but instead of generating a stub, you can configure it to make an arbitrary object of your own the stub. Transfer then injects its generated code into your class, making your inheritance tree very one-dimensional.