As developers, we love the opportunity to solve interesting puzzles. In the past few projects, our teams have explored patterns of code generation to help save time and developer attention. In many of our tools and frameworks, we see code generation in action. If you’re interested in advancing your data access layer more quickly in a Java stack, the Jooq framework offers some amazing ORM capabilities and database-first code generation. .NET developers leverage Entity Framework to generate data access layers based on a database model or C# object model. Many front-end frameworks have created ways to scaffold list or form views. In this post, we’ll explore the idea of implementing your own code generation strategy. These strategies should help developers focus on the interesting business logic of your application, save project time, and improve application code consistency.
This post is largely inspired by Kathleen Dollard, a thought leader in code generation. If you’re interested in digging deeper into these concepts, please check out Scott Hanselman’s awesome podcast with Kathleen Dollard. I appreciate that this conversation focuses on principles that apply to any organization or technology. The conversation is pretty timeless. You should be careful as you apply code generation. Some consider it a code smell. I, however, believe it’s a tool worth considering to help developers focus on interesting work.
Do it yourself: In many cases, you can buy software tools that provide a stock set of architecture or patterns. Kathleen discourages this practice since we’re enabling a third party to influence critical decisions around your application. (security, code standards, organization, etc.) It’s recommended that your team own your architecture and design. Code generation should be seen as a tool to help you accelerate parts of your system that have strong patterns. With that said, favor code generation tools that empower you to express your architecture.
Have SOLID architecture: As you consider implementing code generation in your project, make sure you have firm opinions on code organization, naming, and architecture. Your team needs to define these concepts well before advancing a code generation strategy. Are components easy to unit test? Does the architecture properly apply SOLID principles? In my personal work, I’ve been digging into domain driven design more.
Code generation should protect human effort: In the previous point, we discussed the idea of amplifying great architecture using code generation. It’s also important that human developers can inject custom logic around the code generated concepts. Let’s say we’re code generating a service that writes data to a store. Additionally, the developers need a way to write custom validation logic before writing the record. From an architecture point of view, how do we enable developers to express this custom validation logic? If we change the code generated service, how do we protect and not overwrite the validation logic. Some frameworks I’ve seen leverage base classes to encapsulate code generated elements. Developers extend these base classes and express their custom logic at that level. That’s just one strategy.
Code should match or exceed human quality: While speed is an awesome goal, quality matters more. All code generation strategies should match or exceed the quality that a human can write.
Experiment and Iterate: Like anything else in software engineering, it’s ok to tinker and experiment. My first code generator leveraged XSD(xml schema definition) to generate various classes. In other contexts, I’ve seen engineers make small domain specific languages or entity definitions in JSON. Using these very simple JSON definitions, you can use your favorite NodeJs template engine to transform the JSON into application code. (Handlebars or EJS) My current code generator leverages C# classes for meta data, reflection and Fluid templates for .NET core.
Be intentional about your meta-data: This might be one of my favorite ideas from Kathleen Dollard. One thing that I love about Kathleen’s vision for code generation is the scope. In most cases, code generation has been applied to building data access stuff or simple UI scaffolding. Mrs. Dollard proposes that organizations can be more robust in describing their data model design, data operations, validation rules, and business rules. Since 2009, the domain driven design community have been exploring these core ideas. I’m curious if you can express this rich set of data models and operations in C# or Java code. Using reflection, how much back-end and front-end code can you scaffold?
As always, we love to hear from our readers, what are your thoughts on code generation?
Leave a comment below.