Sponsored Link •
Bill Venners: Test-driven development seems to require less formal thought than Design by Contract. In Design by Contract, you ponder about the abstract contract of types. In test-driven development, you think about one small task at a time. Write a test, implement the code, refactor, and repeat. In Design by Contract, you design at the level of types. In test-driven development, you design in smaller pieces, each step building on the previous. The design of an entire type emerges from this iterative test-code-refactor process.
To what extent are formal contracts required for successful software projects? You suggested that people who are attracted to test-driven development because they don't want to write specifications won't go as far. Why not? How does being formal about specifying contracts, which takes more time and effort up front, help you go farther?
Bertrand Meyer: The word "formal" is scary to many people, so we shouldn't
overplay the formality of Design by Contract. Many contract elements are just relatively
simple affairs, such as
x is positive, or this particular pointer is not
null. This kind of statement accounts for the majority of contract
elements. More complicated elements tend to be expressed by Boolean expressions that
include function calls. You might declare that a particular property, such as that the
account is not delinquent, will hold for a bank
account, and that property is expressed by a
certain function in the class.
People are doing really formal development, and that's a very interesting area as well, but it's probably beyond what most developers are willing to contemplate. One of the things people find attractive in the Design by Contract approach as embodied in Eiffel is that it does not really require extensive training or a major departure from accepted practices. James McKim who is the coauthor with Richard Mitchell of the book Design by Contract by Example, likes to say, "If you can write a conditional expression—if you can write an if statement—then you can write a contract." And he's absolutely correct. There's nothing magical or difficult in contracts. You don't need a PhD in formal logic.
The issue is not so much adopting a completely formal approach to software development. There are people promoting this, and it's a field in which I'm interested in the more academic side of my activities, but it's really not what Design by Contract is about. Design by Contract in very simple terms is stating what you expect and what you guarantee in precise terms in the same way you express what you do.
Bill Venners: By "formal," I simply mean thinking at a more abstract level. When you are writing a unit test for a small incremental piece of functionality, you don't necessarily need to step back and consider the interface of the entire type. In fact, my understanding is that you are supposed to take small steps so that your mind can just focus on adding one small piece of functionality at a time, allowing the larger overall design to emerge out of your many small local decisions.
Bertrand Meyer: This is where I keep wondering whether I have a disagreement or not with the XP crowd. Maybe I do and maybe I don't. It is risky to judge an approach on the basis of how people apply it. It is clear that there are people who have seized on the XP ideas as an excuse not to abstract very much. They may be wrong. They may just be misapplying the XP idea. Here I really don't know. I'd like to have a more extensive discussion with people like Kent Beck and Martin Fowler.
But that being said, if you don't want to abstract, you are really going to be in trouble. Tests are a way to find errors. You may have removed enough errors that your tests pass, and therefore you think you're OK. But if you don't want to abstract more into the general case, then you are really in trouble. This is where the professional responsibility aspect of our work comes in. Many of the major catastrophes of the history of software were caused by stupid details, extreme cases that should not have occurred. These cases were ignored during development and testing because no one thought of them, because they were so baroque, so unlikely, or outside of the box. This is the kind of thing that really often plagues systems: the list that happened to be tested only when it was not empty. But once in a while the list is empty and everything crashes.
You need to abstract a little bit and ask yourself, "What do I expect of this particular data structure? Is it OK if the list is empty, or is it an erroneous case? If it's an erroneous case, whose responsibility is it to make sure the list is not empty?" If you don't do this abstraction, which doesn't require a PhD in mathematics but does require care and generalization, then you're not really fulfilling your duty even if all your tests have passed with flying colors.
Come back Monday, March 8 for the final installment of this conversation with Eiffel creator Bertrand Meyer. If you'd like to receive a brief weekly email announcing new articles at Artima.com, please subscribe to the Artima Newsletter.
Bertrand Meyer is the author of Object-Oriented Software Construction, which
is available on Amazon.com at:
Bertrand Meyer's Home Page at ETH, the Swiss Institute of Technology:
The Grand Challenge of Trusted Components, presented by Bertrand Meyer at the International
Conference on Software Engineering, May 2003:
The Structure and Interpretation of Computer Programs, by Harold Abelson and Gerald Jay Sussman
with Julie Sussman:
Find out more about Eiffel at:
The Eiffel language FAQ:
The 2001 Interview with Programming Expert Bertrand Meyer in InformIT:
(Gratuitously long URL omitted...)
Design by Contract by Example, by Richard Mitchell and Jim McKim: