Andy Hunt and Dave Thomas are the Pragmatic Programmers, recognized internationally as experts in the development of high-quality software. Their best-selling book of software best practices, The Pragmatic Programmer: From Journeyman to Master (Addison-Wesley, 1999), is filled with practical advice on a wide range of software development issues. They also authored Programming Ruby: A Pragmatic Programmer's Guide (Addison-Wesley, 2000), and helped to write the now famous Agile Manifesto.
In this interview, which is being published in ten weekly installments, Andy Hunt and Dave Thomas discuss many aspects of software development:
Bill Venners: In your book, The Pragmatic Programmer, you suggest that programmers fire "tracer bullets." What are tracer bullets? And what am I trading off by using tracer bullets versus "specifying the system to death," as you put it in the book.
Dave Thomas: The idea of tracer bullets comes obviously from gunnery artillery. In the heavy artillery days, you would take your gun position, your target position, the wind, temperature, elevation, and other factors, and feed that into a firing table. You would get a solution that said to aim your gun at this angle and elevation, and fire. And you'd fire your gun and hope that your shell landed somewhere close to your target.
An alternative to that approach is to use tracer bullets. If your target is moving, or if you don't know all the factors,you use tracer bullets—little phosphorous rounds intermixed with real rounds in your gun. As you fire, you can actually see the tracer bullets. And where they are landing is where the actual bullets are landing. If you're not quite on target—because you can see if you're not on target—you can adjust your position.
Andy Hunt: Dynamically, in real time, under real conditions.
Dave Thomas: The software analog to firing heavy artillery by calculating everything up front is saying, "I'm going to specify everything up front, feed that to the coders, and hope what comes out the other end is close to my target." Instead, the tracer bullet analogy says, "Let's try and produce something really early on that we can actually give to the user to see how close we will be to the target. As time goes on, we can adjust our aim slightly by seeing where we are in relation to our user's target." You're looking at small iterations, skeleton code, which is non-functional, but enough of an application to show people how it's going to hang together.
Basically, it all comes down to feedback. The more quickly you can get feedback, the less change you need to get back on target.
Andy Hunt: Having said that, there are times when either approach is appropriate. You might think it sounds silly taking the big guns and firing computers approach. Well, if you're shelling a city, which isn't moving, that's a pretty good way to go. If you're writing software for the space shuttle, or any kind of environment where you really know all the requirements up front and they're not going to change, that's probably the cheapest way to do it. And there are some environments where that is the case. Not many, but that actually does happen. If you're shooting at something that's not a city, something that's moving, then you want to get that rapid feedback.
Dave Thomas: Tying in to what Andy said earlier (In Part III, Good Enough Software) about software having a Heisenberg effect, where delivering the software changes the user's perception of the requirements, almost by definition, your target is moving. The sheer act of delivering the first release is going to make the user realize, "Oh, that's not quite what I wanted."
Andy Hunt: Or even worse yet, "Oh, that's exactly what I wanted. But now having seen that, I've changed my mind. I've learned. I'd now like to do this instead, or this in addition." Just by introducing the software, you've changed the rules of the game. Now the user can see more possibilities that they weren't aware of before. The user will say, "Oh, if you can do that. What I'd really like is if you could do this." And there is no way to predict that up front.
Bill Venners: You say in your book, "In tracer code development, developers tackle use cases one by one." What is a use case, and why do you recommend that we do tracer bullets in use case chunks?
Andy Hunt: Central to tracer bullet development is the idea of a skeleton application, in which one thin line of execution goes end to end. In a skeleton application, you have some bit of functionality—even if it's just the equivalent of "Hello, world!"—that goes all the way from the UI, through business logic, through whatever else is in the middle, all the way to a database. It may do nothing more than put a checkbox value into the database as a Boolean. Whatever the skeleton application does, it does end to end, skeletally thin.
From the skeleton application forward, you might start adding one feature at a time, where each feature implements one use case. You implement the feature, go all the way through, and see if it hangs together. As you steadily grow your application, one feature at a time—this is where tracer bullets come in—you may realize, you're off by a little bit. Well, you still don't have that much code. It's still easier to adjust it and fix your aim. As you grow the application fatter and fatter over time, it will be increasingly harder and harder to make gross changes. But you'll also be getting smarter as the project progresses, because you are firing tracer bullets and getting feedback. So when the requirements are more volatile, the code is easiest to change. Later the code does become harder to change, but by then you know more and less change is required.
Bill Venners: Another development technique you talk about in your book is prototyping. What is prototyping, and when it is appropriate?
Dave Thomas: Prototyping is when there is a specific aspect of something—whether it's an interface, or an algorithm, or a performance problem—that you want to investigate.
Andy Hunt: Prototypes are for your learning.
Dave Thomas: Yes, prototypes are a learning tool. For example, the requirements may say you need to get 10,000 transactions an hour through the database. But you may know that the highest throughput you have ever gotten with that database is 5000 transactions per hour. You need to find out if this is actually going to work or not. So you hack together a real ugly little script that poke 10,000 transactions in an hour and see if it works. That's a prototype.
Andy Hunt: And maybe the script doesn't even go through your code. You might not even know if the database can do 10,000 transactions in an hour. You may start with a prototype to see if the database can handle the load, because if the database can't do it, there's no way your application on top of the database is going to be able to do it. Prototypes allow you to investigate.
Bill Venners: Is their a danger of management trying to turn the prototype into a tracer bullet?
Dave Thomas: Prototypes by their nature are not designed to be long lasting code. Prototypes are designed to be thrown away. They're one-offs. It is inappropriate to over-engineer a prototype. A prototype is like a town in a western movie. It's all facade. There's nothing behind it. You cannot move in and raise a family in one of those houses.
Come back Monday, April 28 for Part IX of this conversation with Pragmatic Programmers Andy Hunt and Dave Thomas. If you'd like to receive a brief weekly email announcing new articles at Artima.com, please subscribe to the Artima Newsletter.
Andy Hunt and Dave Thomas are authors of The Pragmatic Programmer, which is available on Amazon.com at:
The Pragmatic Programmer's home page is here:
Dave Thomas was not the first person I've interviewed who mentioned the arcade game Whack-a-Mole. James Gosling also called upon the versatile Whack-a-Mole metaphor while pointing out that it is sometimes hard in engineering to know if you've solved a problem or moved it:
The Agile Manifesto is here:
Ward's Wiki, the first WikiWikiWeb, created by Ward Cunningham, is here:
Extreme Programming: A Gentle Introduction:
XProgramming.com: An Extreme Programming Resource:
Bill Venners is president of Artima Software, Inc. and editor-in-chief of Artima.com. He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Bill has been active in the Jini Community since its inception. He led the Jini Community's ServiceUI project that produced the ServiceUI API. The ServiceUI became the de facto standard way to associate user interfaces to Jini services, and was the first Jini community standard approved via the Jini Decision Process. Bill also serves as an elected member of the Jini Community's initial Technical Oversight Committee (TOC), and in this role helped to define the governance process for the community. He currently devotes most of his energy to building Artima.com into an ever more useful resource for developers.