I’ve described TDD for years as a “learning-to-design technique”, in which we can use a mechanism similar to the one we use to acquire language skills. How did you learn to speak your native language? You probably did something like this:
- You mostly listened for a long time to people speaking the language around you.
- At some point, you began speaking very simple sentences.
- As you spoke sentences, you noticed how people reacted to what you said, looking for signs that they understood you.
- Some people corrected you, instructing you to say this instead of that.
- As people corrected you, you extracted rules, guidelines, and principles to build “correct” sentences. (This part gets fuzzy; stay with me.)
- You used these rules, guidelines, and principles to inform how you constructed new sentences.
You’ve never stopped doing this. The language you speak became an ongoing negotiation with other speakers, involving experiments, evaluations, mutual feedback, attempts at correction, extracting new rules, guidelines, and principles, repeating until death.
I think that TDD provides a way to learn design this way. It goes beyond merely programming because it presents the programmer with example after example of code subject to constraints like “I can easily test this” or “I can extract this from its context to run it in isolation” or “I can add new behavior by adding code rather than changing it”. You can argue that one gets these benefits from merely reading and talking about code, but TDD encourages the programmer to carry on a conversation with the code, thinking alternately about “how should this behave?” and “how should I design this part?” I think that this conversational style builds up the experience bank more steadily and more extensively than more traditional write-lots, read-rarely approach. If nothing else, TDD encourages the programmer to think differently about the code.
Refactoring plays the central role in this approach. Refactoring involves evaluating the code as it stands, looking for problems, articulating those problems, proposing an specific improvement, then changing the code gradually to make that improvement. (I wouldn’t want to refactor much without tests, and I probably wouldn’t write enough tests if I didn’t write those tests first.) Refactoring exposes the programmer to example after example of designs that might or might not have problems, and helps the programmer compare those to examples of designs that don’t have those same problems. The programmer has the opportunity to compare “before” and “after” and reflect on whether the “after” represents a true improvement over the “before”.
Article shared by Ashok B
Leave a Reply