Before jumping into the critical attributes of a code generator for your project, let us start by answering the “why” you would use one.
Benefits and pitfalls of code generation
The key benefits expected by using code generation are the following:
- Productivity: by writing less code, especially repetitive code, you save time.
- Maintainability: less manually written code means fewer bugs and less maintenance.
- Quality: homogenizing the code increases overall quality, especially with a team of developers with different levels of experience.
- Evolution: abstracting from lower layers can help in the portability dimension toward various platforms or versions in the long run, increasing the evolution capability.
Though there are expected benefits, there are pitfalls in using code generation:
- Complexity: by adding a level of abstraction, complexity is increased and often much beyond what has been expected at the beginning once you extend the generation perimeter in terms of technology and functionality.
- Evolution: though this point is mentioned as a benefit, it is also a potential pitfall, as one can also be slowed by using a generator that does not follow innovation at a sufficient pace or does not evolve to support a technology becoming critical for your project.
Those challenges are quite well explained in this valuable article about code generation from Federico Tomasetti. Here is also an introductory article to the principles of code generation.
Writing your own generator?
Though it is very tempting to write your own code generator, as many developers love to solve complex problems and as it is also a way to fully master your architectural choices (see, for example, Kathleen Dollard’s point of view in this article about principles of code generation), it is also a risky decision.
The thing is that complexity is often underestimated by semi-experienced developers, confident enough while gaining some benefits in the early stages of using their own approach, but not anticipating how complexity will scale up in a nonlinear way. You will end up spending your whole time developing the generator instead of your project.
Except if you are part of a large enterprise with hundreds of developers, which makes it relevant to build your own code generator for the team, it is likely a bad idea to try to build one. You can address the legitimate concerns about architecture by choosing the appropriate code generator(s) for your environment and technology stack.
How to choose your code generator by checking 7 critical keys to success
In our view, there are 7 critical keys to being successful in your projects while using a code generator. Make sure you get a good idea of these keys before it’s too late in your project.
Though it might seem obvious, the code generator should reduce the number of manually written code lines in a completed project. In our experience, this reduction ends up taking care of 90% of the boilerplate code, often counting from 30% to 50% of the total code. Bugs should be reduced proportionately, as there should not be any bugs (at least theoretically) coming from the generator.
Some generators also simplify the syntax, making the coding less error-prone. If a generator requires more coding and description than what you would do manually, stop here; code generators should simplify your work, even if it is normal to have a little bit of a learning curve when starting.
The code produced by the generator should not impact performance negatively, except marginally. As an example, it may consume a bit more resources, as the generated code is usually a bit more verbose. The code generator should have been designed with execution performance as a focus to be viable over the long term.
Some generators rely on a heavy abstraction model, which is solved at runtime; this does not behave well in production once the application gets larger and with significant production data volumes.
The code produced by the generator should be very efficient at execution and it is also better when it is developer-readable—though sometimes not strictly necessary in fully-abstracted areas—but it is not required to be identical to human-written code.
For example, SQL code generators often add ‘WHERE 1=1’ clauses to simplify the generation process.
Still, human-readability can be useful if there is some debugging that requires digging into the generated code for troubleshooting.
The important thing in the end is to homogenize quality at the top level rather than bottom level.
Open to custom code
Whatever the extensiveness of the code generator and its broad spectrum of features, I do not believe in complete generation of the code. And even if such a powerful generator would exist, we would be outside of the developer discussion.
For this reason, it is very important to use a code generator that has the proper hooks and placeholder to integrate manually written code with the generated code. It can be integrated before the generation process, in the middle of the generated code, or through post-processing after generation.
Of course, I exclude from the discussion the one-shot usage of a code generator. I assume that the code generator is properly designed to regenerate the code without interfering with manual code and protected from the risk of manually overriding the generated code without a process that has been designed to allow this.
Development tool integration
One should remember that productivity is a key promise of code generation. Therefore, it is critical that the code generator is properly integrated in the development tool.
A developer who benefits from automated process but loses the productivity of the development tool by losing critical features such as debugging or powerful editing features such as autocompletion, does not save time in the end.
For the same reason, it is important to integrate in continuous build processes that mean seamless integration in the devops processes and tools. One should be able to add a ‘continuous generation’ step in the overall build process.
For the same reason, reasonable generation time is critical. If the speed of the generation process is too slow, not only does the developer lose time, he loses a bit of concentration of focus.
Of course, one should remember that the generation also replaces manual coding and it is acceptable to have some moments where you wait a little bit, especially if you regenerate a significant part of an application, but there is a matter of balance here, to make sure the developer does not spend half of his day looking at the generator processing the code.
Technology evolution support
Last but not least, the technology support of a generator is a key element in your final decision if you have to choose one. Of course, it has to support your current target architecture and technologies, potentially with portability to different platforms or databases.
But it might be a good idea to make sure it will evolve to support further innovation or future platforms by the way it is designed. Keep in mind that a broader generator in terms of features will by nature be a bit slower to adjust to new technologies.
It is also important to check how compatibility will be guaranteed for a sufficient period. One key indicator is the long-term existence of the generator and the current adaptation and compatibility to more recent technologies.
Choosing a code generator is not so easy and it is critical to consider the elements discussed here, knowing there are numerous tools available as one can see on the Wikipedia page. If you evaluate one for your project, keep our 7 recommendations in mind.
At SoftFluent, we have a long history of selling our own code generator, with a recent version now called SoftFluent Code Modeler (full link to documentation directly available on the website). It basically helps you build a powerful portable business layer from a design model.
Syncfusion provides more than 1,500 custom controls to ease the work of developers on various platforms. Please have a look and use them in your application development: