A popular approach to reducing the costs and risks of building an application is to use some form of code generation technology to get a quick first cut of the source code artefacts. But code generation has its limits in practical uses and can become less efficient as an application matures and changes over time.
The Model-View-Controller (MVC) Architecture Approach
The standard approach from the common MVC architecture patterns is to use the model class as a source for a code generator. The model class will at a minimum define a set of fields and their associated data types. We can decorate these fields with attributes to specify whether they are required, some validation options, validation messages, etc.
Code Generation for Databases
From the Model class we can create some TSQL statements to create tables, views, and stored procedures for insert, update, select, and deleting the records in the database. This is a good starting point for the database, but we have to consider what may still need to be customized:
- Will my table need indexes to optimize how I will search the rows?
- Will my updates always modify all columns? Should I be selective about which columns can be updated by different types of users? What about depending upon the state of the record? Other custom business rules? How about by device type?
- Some complex data models have complex table hierarchies that may require joins across many tables – how will I model that?
- For example, how do I tell my “Order” class that it is a child of the “Customer” class and contains “Order Line” classes?
- How will I optimize complex multi-table joins?
Of course, I could keep adding attributes to my model class, but at what point does it become a diminishing return? If the extra attribute is essentially the CREATE INDEX statement – have I actually saved any time, or just added something else that could go wrong and will need to be maintained?
What happens if I decide to add a new field after I already created my TSQL? Does the code generation deal with altering existing TSQL objects?
Here is a link to the CREATE TABLE help for MS SQL Server. Will the code generator deal with all of that? What about all the TSQL objects needed to maintain your database?
The point is that your code generator will only get you so far before you will be forced into custom code, and after that your code generator becomes less useful.
Code Generation for the User Experience
For most applications the limitations of code generation are even harsher when we consider the user experience.
We can use the model class to create view forms that will list records (for example, “Orders”), or allow us to view/modify details based on the fields in the model. Using our “Customers and Orders” example:
- What about those Customers and Order Lines? Lots of extra view pages? What if I have several types of Customers, Orders, and Order Lines; all of which have a different set of fields?
- Do I have a table of Orders on the Customer and Order Lines on the Order? Already starting to do some customization?
- What if the fields on the Order are dependent upon the state of the Order? Can they be seen? Are they editable? Are they Required? Is there a business Rule that can be overridden by a user with a manager role?
The permutations and combinations quickly escalate the complexity beyond what can be done by adding attributes to class members.
Your code generator gets you so far, but as soon as you modify the generated form, then what happens when you change the model class?
What About Canvas Drawing?
There are code generators that work by allowing the user to drop fields on a form canvas and then generate the code based on the field properties defined on the form.
Essentially, they are providing a graphical approach to creating the underlying model class and suffer from the same limitations.
Are Large, Pre-Developed SaaS Applications the Best Option?
Consider a tool like Microsoft Dynamics. It comes with a comprehensive Universal Data Model and a set of built-in workflows and optimizations. If you are trying to build a CRM application that integrates with Office 365, then it’s going to be a great fit. You can customize it, but that does tend to be slow and require expensive professional services expertise. The recommendation is to first try to fit your requirements to what comes directly out of the box and only then consider customizing things you really need that don’t otherwise fit. But this may result in the business being forced to “shoehorn” their business processes into an application’s prebuilt functionality. And as more changes need to be implemented to meet business requirements, the process of implementing changes can get more expensive and time-consuming.
Most mature SaaS solutions are variations of the MS Dynamics story. They were first applications with a very specific use case at the heart of their user experience. They then added extensions with minimal code generation so that you could customize their core functionality.
This is a potential option for stable businesses that “fit” the pre-built solution, but they are “code heavy”, slow to evolve, and expensive to maintain and expand.
Does Great Ideaz Use Code Generation?
At Great Ideaz, we have been creating code generators for different purposes for over 12 years (and my experience is over 30 years). We have lots of experience with how far you can go before you hit the limit of diminishing returns.
We still use code generation for simple database objects like tables, views, and stored procedures. Our rule is that any object created using code generation can’t be customized after creation. This means that code generation must be able to simply delete and recreate the object. Custom database objects must be held with the data model so that they can be immediately reapplied after code generation has completed.
We don’t use code generation at all when it comes to creating the user experience. We found that simple code generation models were always more trouble than they were worth. By the time we had a code generation model that was complex enough to build the sort of user experience we wanted, we had outgrown the need to generate the code pages entirely.
We now use our UX Creator app in trellispark to configure a data model that can be used both to build the database objects, and dynamically render the user experience at runtime. The result is a “pageless” approach to building the user experience that we wrote about in this blog post.