asn’t it George Jetson who went to “work” each day and pushed a few buttons to generate all his deliverables without lifting a physical or mental finger? Ah, would that our computers would write all the code we don’t feel like writing (and write it so there are no bugs to fix, either!), leaving us free to focus on the fun, challenging, or unique aspects of our applications.
The notion of software that writes software has been around for decades, but it is only recently that developers are taking this notion of code generation seriously. What changed? Code generation changed?and much for the better.
Your Father’s Code Generation
|Figure 1. Workhorse: Automatic code generation promises to build about 80 percent of your application for you.|
Some of you may remember when RPGII was introduced back in the 1960s and 1970s. This was an initial attempt at streamlining the development process by providing a higher-level language that generated code for you. In fact, 4GLs and 5GLs attempted this again in the ’80s. High-level languages are effective at generating code, but only when you give them a highly structured environment. 4GLs work best when nearly everyone in the development team uses the same language, for the same reason that a development shop would standardize on VB or C#. The downside to 4GLs is that they are proprietary in nature, so mastering one can limit one’s career mobility and ability to work in different application areas. It is for this reason, I believe, that there is no longer any 5GL on the horizon for code generation.
In the late ’80s and early ’90s came Computer Aided Software Engineering (CASE), which also worked well for highly-structured applications. CASE, as Abe Lincoln was fond of saying, “appealed to the people to which these sorts of things appeal.” It worked well for highly structured, organized thinkers?those who write all the architecture down before starting the development process. However, this does not lend itself to the iterative style of development used by most developers today.
CASE tools did not actually generate code, but they did certainly provide great documentation and layout files. That was, of course, CASE’s downfall. The tools never generated anything terribly useful for actual application development. However, CASE does hold the distinction of being the first technology to hold out the promise of code generation and not deliver.
Another category of tools that promised great things is what I would call bleeding edge research tools.’ These ranged from AI systems to genetic algorithms. While they certainly have a number of uses, they are not practical to the meat and potatoes application development that most corporate developers do day-in and day-out.
And finally, having stood the test of time and still in use today is what I refer to generically as compiler-compilers. You may know these as YACC, JavaCC, and so forth. These are code generators, not application generators, because they focus on creating one aspect or component that lends itself to being regenerated over and over again. For example, YACC is a tool that generates a parser for a specific language syntax.
Evolving from the compilers are single-tier code generators. Some of the best of these will give you the flexibility to generate custom code for your specific database schema. Others will generate a schema based on your object model. For these tasks, they can work well. But they are not for generating a complete, custom application.
|Editor’s Note: The author, Alan Fisher, is the cofounder and chairman of Iron Speed, Inc., a vendor of code generation products. We have selected this article for publication because we believe it to have objective technical merit.|
Making Code Generation Work Today
Since these various attempts were introduced, a number of things have transpired to make code generation faster, stronger, and smarter than ever before. What’s different? In a word: Standards.
- Architecture: Today, we have a strong notion of what application architecture ought to be. A two-tier architecture for client-server applications and the more contemporary three-tier or n-tier for Web applications. Each tier can be segmented and defined.
- User Interface: There used to be dozens of standards for the user interface, everything from DOS to the 80-character and 32/70 screen displays, and now of course there are Windows and MAC-based formats. However, for Web applications, we have a common standard: HTML. And every user is guaranteed to have a modern Web browser.
- Language: The number of programming languages in use is large, but most of our primary corporate application development is done in one of three languages: Visual Basic, C#, or Java.
- Database: Day-to-day corporate applications are almost exclusively SQL now, notwithstanding some of the modern XQuery XML databases.
With the issues above more or less decided, we’ve been able to move forward, introducing modern techniques that get us much closer to the dream of code generation.
Modern Code Generation Techniques
Perhaps not surprisingly, the list of modern code generation techniques reads a little bit like an the “outdated” code generators mentioned earlier, with different names. Sort of like bell-bottoms and leisure suits; they keep coming back to haunt us in new fabrics.
For instance, the MDAUML (Model Driven Architecture / Universal Modeling Language) approaches create a scenario like the CASE tools: UML works very well in shops that have an almost religious conviction about the application planning and development process. However, they don’t work well for most of us. We like to sit down with our customers, whether internal or external, and show them screens right away. We want to toss stuff up there and iterate from the feedback we receive.
Another take on the component libraries is the Enterprise Templates feature found in Visual Studio.NET. These templates are planning and design modules that allow you, among other things, to build code snippets in the IDE itself so it can be shared across a number of applications.
Many of you may have done the same thing by building your own code generators. There is a great Web site called www.codegeneration.net (operated by DevX author Jack D. Herrington) that has a large user forum on building your own code generator. Again, if you find that you are building the same portions of applications over and over again, it may behoove you to construct a single-purpose code generator.
Declarative code generators are a new class of code generators that really do deliver on the promise of generating your application, not just portions of it. Declarative generators work by allowing you to simply state what it is that you want, rather than modeling it out. They are particularly suited to the iterative style of development. And let’s face it: Right or wrong, this iterative approach is what we use in practice.
A Declaration of Automation
Declarative application generators quickly generate the large, “routine-but-necessary” parts of your application, freeing you to focus on its unique aspects which are outside the scope of any code generation technology.
|Figure 4. Custom, Complex Pages: In the end, what you need is to generate great looking applications with advanced functionality, without doing much work.|
Declarative code generation works by using a declarative semantic to define what functionality, layout, and performance you want in your application. For instance, XML is a familiar and conventional way to state what it is you want in a declarative style, and so is used by many declarative code generators.
By way of example, the declarative application generator made by my company?Iron Speed Designer?accommodates highly iterative development. Basically, you build your n-tier application with two inputs:
Using Iron Speed Designer, the controls represented by code generation tags in your application’s web pages are “bound” to specific database tables, fields, views, and queries. This control-to-database binding information is the foundation used by Iron Speed Designer to generate your application to your custom specifications.
|Figure 5. Declarative Process: Declarative code generation alloows you to declare what you want using either page layout files or database schema.|
Why is this declarative method so important and useful for modern .NET application development?
- This is how developers work. Most applications are architected based on a couple of HTML pages and a database schema. Developers build the application from those starting points. The declarative application generator does the same thing?it reflects your user interface layout and database as inputs and generates a large volume of custom infrastructure programming in a fraction of the time of hand-coding.
- End users of your application are familiar with the Web and with sophisticated, highly intelligent forms and user interface navigation features. Most developers dread the inclusion of these features?such as paginated reports, hierarchical navigation, filtering, and full-text search?because the amount of time they take up is not proportional to the challenge or interest they create. Application generation tools automatically include these sorts of features, freeing you to focus on the more interesting work.
- Connecting individual pages to the database is mind-numbing work. Visual Studio and Visual Studio.NET do all the work of connecting events and properties to the controls in client-server applications. However, by using application generation tools, you don’t have to worry about manually writing ASPX or SQL. Moreover, you don’t have to worry about transaction management, such as concurrency handling and cursor management. The application generator handles this for you.
In the end, regardless of which type of application generator you choose, you want the generated code to be something you can get your arms around. A modern application generator should:
- Start from scratch with an application-specific data model.
- Create everything needed for a functional three-tier application, link everything together, and deliver a bug-free, functional prototype of the desired application.
- Automatically generate all of the source code for the application, native to the target platform and optimized for the production environment.
- Provide complete and well organized source code that’s easy to modify and extend.
- Automatically preserve and reintegrate customizations or extensions during subsequent application regenerations.
Extending the Code Generator Itself
Let’s consider this last point in a bit more detail.
Automatically preserve and reintegrate customizations or extensions during subsequent application regenerations.
Most good declarative code generators are themselves extensible. A major drawback of past efforts at code generation is that the tools were one-way streets: Once you push the generate button you own the code. That just doesn’t work for today’s iterative style of development.
Ideally, the code generator should allow you to put your extended or modified custom code back in, and allow that custom code to become part of what the code generator tool can generate for future applications. Rather than just spit back out what is put in, the code generator adds value by creating a repository of code assets, making the customized code written for one application more flexible and multi-purpose. You (and developers anywhere in your organization) should be able to leverage these code assets over and over again.
In essence, the code generator does what no developer has time or incentive to do: It manages selected application code and creates a knowledge base of re-usable code that meets the specific standards and practices of that unique organization. Now, code written specifically for one application can be regenerated for future application development. All without any additional work or drag on the initial application’s project schedule.
Specifically, you might leverage custom code in the following areas:
Presentation Layer: Because many large enterprises require that locally constructed applications conform to a distinct set of functionality as well as look-and-feel, the custom HTML page layouts used in one application can be re-used in future applications.
Application Layer: Any aspect of the application logic should be able to be extended and then re-generated for future applications. A simple example is generating different order validation logic for orders coming from outside your system (i.e.: from partners) than for those originating inside the company network (i.e.: from the inside sales team).
In the data validation example shown below, I added additional logic to the “safe class” in order to override the validateData function. A “safe class” is generated once and never overwritten. Thus, it does not have to be rewritten for future applications if your code generator can adopt it and make it available for future development efforts.
'This Handler implements server side validation logic_
for the V_CityFieldCustomValidator controlPrivate Sub V_CityFieldCustomValidator_ServerValidate_
(ByVal source As Object, ByVAl args As_
System.Web.UI.WebControls.ServerValidateEventArgs) _Handles V_CityFieldCustomValidator.ServerValidate 'get the value to validate Dim value As String = Me.V_CityFieldCustomValidator.GetValueToValidate() If (value <> "Mountain View")) Then Me.V_CityFieldCustomValidator.ErrorMessage_
= "Please move to Mountain View." args.IsValid = False End IfEnd Sub
After acquiring the City field, we compare it to “Mountain View.” If the City is not Mountain View, then we return “False,” generating an error message, and keeping the user on the page. If the validator returns “True” the user proceeds to the next page.
What’s the Bottom Line on Code Generators?
In the end, you need your development tool to generate a lot of code very quickly for those aspects of the application that you really don’t want to build. Of course, code generation is not a magic bullet. It may generate a majority of the application, say 80 percent, but it will never be able to do the entire application for you. For now at least, George Jetson is still just a cartoon.