Introducing Code Generation - Breaking Down the Code Generation Process
(Page 7 of 13 )
If you separate the jobs you can do effectively with tools from those that deserve handcrafted attention, you’ll get the job done faster, and your results will be more precise. Precision means consistency—you’re reproducing the same thing. Accuracy means your output is correct. Code generation can make you precise, but it alone can’t make you accurate.
For accuracy, you want a process that guides you to effective output. A full-cycle development methodology based on five steps of code generation lets you create better applications significantly faster.
Understanding the Five Steps of Code Generation The conscious code generation process I use consists of five steps, as shown in Figure 1-1.
As you can see from Figure 1-1, the five steps are as follows:
- Design architecture.
- Collect metadata.
- Build and run templates.
- Handcraft code.
- Tie it together with integration and testing.
The pyramid in Figure 1-1 illustrates that you’ll want a strong architectural basis for metadata collection. Your architecture determines what metadata you need. Strong architecture and valid metadata are the basis for accurate templates to generate code. Handcrafted code relies on generated code. You integrate and test the whole thing. Each step relies on the previous one.
These steps aren’t always sequential, and there certainly isn’t a waterfall-style progression between them. They generally occur in a sequence because each builds on the output of the previous step. For example, you need to know what you’re building before you build it, and you can’t tie it all together in implementation until you have a complete system. But the process lends itself to iterative refinement, as shown in Figure 1-2. Each step lays the groundwork for the next step, but it also provides information for refining the previous step.
Designing Architecture
Architecture overarches the other steps. It tells you how to build your templates and what metadata to collect. You design the architecture for code generation. It doesn’t tie you to any particular architectural pattern.
*******************
NOTE Although you can use whatever architecture you’d like, Chapter 8 presents templates for a very robust middle-tier architecture based on Rockford (Rocky) Lhotka’s Component-based, Scalable, Logical Architecture (CSLA). Chapter 8’s “Additional Reading” section contains a full reference to this book. Chapters 9 and 10 use this middle tier in generated Windows and Web user interfaces.
Many of you are working in an environment where your architectures are already developed and you know what you want to build. Specifically, I assume you probably use a three-tier or n-tier architectural approach—or at least understand that terminology. If that’s not the case, there are other books focusing on architecture. The highest payback for code generation is creating middle-tier data containers and data access layers, so a lot of the code in this book focuses on those areas.
******************
NOTE Design and architecture are vague, fluffy terms. I don’t want to challenge your current semantic understanding of them. From a code generation perspective, design and architecture encompasses all the work you do to understand what your code generation output should look like.
The easiest way to move from design/architecture to code templates is to create a sample file and test it. This example source code file illustrates what you’re creating, and I’ll call it your sample file or target file. Once you know it’s right (you can significantly enhance it later), you can express it in any of the code generation techniques using a varying amount of cut and paste. You can then confirm that your code generation is doing exactly what you want by comparing your generation output with your target file using WinDiff, another comparison tool, or even Word. I’m so reliant on this technique that even when creating the “Hello World” examples, I first created a target source code file and then copied and pasted it into the template.
Transferring code from a target file to the template is one of the places I prefer XSLT code generation. If I’m using brute-force or CodeDOM generation, I have to split the code into individual output statement strings. With XSLT, I copy the entire target file in, then replace variable blocks, delete some code, and organize the result.
***************
TIP Create and test a sample class for each template. As you translate your sample code into templates, you’ll discover or confirm your metadata requirements.
Collecting Metadata
Once you know what you’re going to build, you need to capture the metadata that drives the code generation process. This metadata defines details of your application, such as database tables, fields, and stored procedure details. The metadata tailors the generated code to your specific application and environment. Metadata literally tells the template patterns how to implement themselves, so you can’t create quality code-generated systems without quality metadata. For simplicity, I’ll assume you’re expressing metadata as XML. This is the most straightforward mechanism and is immediately accessible to all programmers on all platforms. It’s also the required metadata format for XSLT code generation.
Metadata for business entities or middle-tier data containers are generally based either on your database or a parallel description of your business objects. This metadata includes the predictable stuff such as column names, types, relations, and nullability. It potentially includes a great deal of additional information, including constraints, captions, and information to create lookup combo boxes. All three output mechanisms directly use this metadata.
In Chapter 2, you’ll see details of metadata collection. Chapter 6 extends metadata to a simplified Object Relational Mapping (ORM6), which allows you to define indirect mappings between your database and middle tier. Chapter 9 then shows the benefit of preprocessing your input metadata to tune it to the requirements of a specific set of templates.
Outputting Code
You need tools to perform code generation. You need to be able to do your code generation at the touch of a button. Your tools need to provide both flexible and reproducible code generation. Flexibility is important because during development you’ll probably want to create a single class to initially test your generation (this saves you from generating hundreds of repetitive syntax errors). You also need reproducibility, including being able to perform the same code generation
6. ORM is one of many phrases and acronyms ambiguously used for different concepts. It can also mean Object-Role Modeling, which is an aspect of UML.
two or three years from now to support a change made during your maintenance cycle. Chapter 3 includes a tool to manage code generation via any combination of these three mechanisms.
You may begin to write a large percentage of your application using code generation. The percentage of your application you can generate depends on your specific application and how much of it can be tied to patterns. Just like recognizing common code is a skill necessary for traditional refactoring into generic subroutines, it takes skill to find similar patterns.7 A side benefit of code generation is that you’re forced to decompose your application into these patterns, learning more about how applications are actually structured. Once written, each template can be applied to a near infinite number of individual metadata definitions. The only real limit is the size of the XML metadata file, and the pragmatic limit is the practicality of the resulting runtime.
*****************
TIP Although you can use any of the three generation mechanisms described in this book (or variations on them), you’ll probably want to settle on one mechanism. You can’t really combine them within the generation of one file, and you’ll limit reuse if you use different techniques to create different output files. However, the harness in Chapter 3 supports heterogeneous code generation if you choose to use different mechanisms for different files.
This chapter is from Code Generation in Microsoft .NET by Kathleen Dollard (Apress, 2004, ISBN: 1590591372). Check it out at your favorite bookstore today.
Buy this book now. |
Next: Writing Handcrafted Code >>
More .NET Articles
More By Apress Publishing