There’s no denying it—applications are getting harder and harder to write. User interfaces in particular are becoming increasingly sophisticated. Twenty years ago, the average application would have a glass teletype interface (if it had an interface at all). Asynchronous terminals would typically provide a character interactive display, while pollable devices (such as the ubiquitous IBM 3270) would let you fill in an entire screen before hitting [SEND]. Now, users expect graphical user interfaces, with context-sensitive help, cut and paste, drag and drop, OLE integration, and MDI or SDI. Users are looking for Web-browser integration and thin-client support.

All the time the applications themselves are getting more complex. Most developments now use a multitier model, possibly with some middleware layer or a transaction monitor. These programs are expected to be dynamic and flexible, and to interoperate with applications written by third parties.

Oh, and did we mention that we needed it all next week?

Developers are struggling to keep up. If we were using the same kind of tools that produced the basic dumb-terminal applications 20 years ago, we’d never get anything done.

So the tool makers and infrastructure vendors have come up with a magic bullet, the wizard. Wizards are great. Do you need an MDI application with OLE container support? Just click a single button, answer a couple of simple questions, and the wizard will automatically generate skeleton code for you. The Microsoft Visual C++ environment creates over 1,200 lines of code for this scenario, automatically. Wizards are hard at work in other contexts, too. You can use wizards to create server components, implement Java beans, and handle network interfaces—all complex areas where it’s nice to have expert help.

But using a wizard designed by a guru does not automatically make Joe developer equally expert. Joe can feel pretty good—he’s just produced a mass of code and a pretty spiffy-looking program. He just adds in the specific application functionality and it’s ready to ship. But unless Joe actually understands the code that has been produced on his behalf, he’s fooling himself. He’s programming by coincidence. Wizards are a one-way street—they cut the code for you, and then move on. If the code they produce isn’t quite right, or if circumstances change and you need to adapt the code, you’re on your own.

We are not against wizards. On the contrary, we dedicate an entire section (Code Generators, page 94) to writing your own. But if you do use a wizard, and you don’t understand all the code that it produces, you won’t be in control of your own application. You won’t be able to maintain it, and you’ll be struggling when it comes time to debug.

Don’t Use Wizard Code You Don’t Understand

Some people feel that this is an extreme position. They say that developers routinely rely on things they don’t fully understand—the quantum mechanics of integrated circuits, the interrupt structure of the processor, the algorithms used to schedule processes, the code in the supplied libraries, and so on. We agree. And we’d feel the same about wizards if they were simply a set of library calls or standard operating system services that developers could rely on. But they’re not. Wizards generate code that becomes an integral part of Joe’s application. The wizard code is not factored out behind a tidy interface—it is interwoven line by line with functionality that Joe writes.[1] Eventually, it stops being the wizard’s code and starts being Joe’s. And no one should be producing code they don’t fully understand.

Challenges

  • If you have a GUI-building wizard available, use it to generate a skeleton application. Go through every line of code it produces. Do you understand it all? Could you have produced it yourself? Would you have produced it yourself, or is it doing things you don’t need?

Footnotes:

[1] However, there are other techniques that help manage complexity. We discuss two, beans and AOP, in Orthogonality, page 31.


Extract from The Pragmatic Programmer Copyright © 2000 Addison Wesley Longman, Inc. Reproduced with permission.

Any trademarks are the properties of their owners