Here are a few more words on the sound bite lines, indicated by sb , that litter the book, as well as a few on bonus sound bites not found in the book.
Are the objects helping us? (Chapter 31, page 482)
Sometimes as we re programming along, things go very smoothly. It s as if all the objects and methods are reaching out, always ready to help us. Other times, it seems that they are hiding, ducking out of the way, fighting us for every inch. If we re sensitive to these feelings, we can begin to sense when the code we re working with isn t as well-designed or as well-structured as it needs to be. Do you have to tell some object about ten things before it will do anything useful? It s not helping ”maybe you can fix it, or find a better helper.
Are the tests helping us? (Chapter 31, page 481)
Usually we ll find that our tests lead us through new areas and protect us as we change things. But sometimes they seem to let us down. Are bugs cropping up in some areas of the code? Even if we are using Find a bug, write a test, we might see continuing weakness in some area of the code. Code weakness can slow us down profoundly. It can be worthwhile to think about and install a new approach to testing that area.
Automated tests record our intelligence for later! (Chapter 5, page 65)
Are we having trouble creating some new chunk of code, even using a test-driven approach? Are the tests hard to write or hard to make work? Consider turning attention to the tests for a while. Test by using a different approach, attacking a different corner of the problem or from a different angle.
If you re like me, sometimes you write a little patch of code to learn how some object works and to get a sense of how to use it. My habit, formed over many years , is to write a little main program that tries something and perhaps prints a few values. I make it work, learn from it, and then throw it away.
I m trying to train myself to write a TestFixture instead, which has two advantages. First, using the test-oriented part of my brain seems to help me learn a little more. Second, the test records the use of the object, and the results, in an easy to find form for later. Give it a try ”you might like it!
Begin with a test. (Chapter 25, page 323)
As programmers, we tend to think in terms of algorithms and solutions. We see a problem and visualize a way to program it. And there s great joy in putting some sweet little algorithm together. For me, though, that way often leads to debugging. I write a bunch of code, finally get around to testing it, and it doesn t quite work.
The discipline I try to use is to say to myself whenever I sit down to program, Begin with a test. Sometimes I listen to myself and actually do it. It always works better when I do.
Build simple scaffolding and then improve it. (Chapter 17, page 216)
Because programming is so much fun, it s easy to get carried away, building complex software to support simple needs. Because infrastructure doesn t please the customer, features do, we ll often be more successful if we build just enough infrastructure to the current situation and don t elaborate it beyond the current need. What we build needs always to be robust, well- tested , well- crafted. But we can leave off the bells and whistles, until the customer calls for ringing and hooting.
See also YAGNI ”You Aren t Gonna Need It .
Card, Conversation, Confirmation. (Chapter 6, pages 71-72)
XP-style planning is in some ways my favorite part of Extreme Programming, although we barely touched on it in this book. The techniques can help a team focus on what s important and what should be put off, they can help us figure out how long things will take, and they can help us keep track of how we re doing. If you decide to learn more about XP planning, you should keep three things in mind:
Card The names of stories, and perhaps a few words about them, are written on cards. These cards are tokens representing the requirement, and we can use them to lay out a schedule, to signify that we have accepted responsibility to implement a feature, or as part of a display of what s done and what s left to be done. But the card is not the full requirement, just a token containing the requirement s name .
Conversation There is an exchange of information between the Customers, the people who understand the need, and the Programmers, the people writing the program. To build a feature, the programmers need a deep understanding of what needs to be done. This knowledge can be provided by written requirements specifications as part of the Conversation, but we call it Conversation to emphasize that understanding comes faster and better in a personal conversation than in passing documents back and forth. So write what you must, and explain as much as you can, face to face.
Confirmation No matter how much we write, and no matter how much we talk, there will be misunderstandings. If we code according to a misunderstanding, the customer won t be happy. Tightening up our documents and lengthening our review cycles really won t help ”human language is inherently ambiguous. Therefore, express the details of story requirements unambiguously, in Customer Acceptance Tests. Getting these tests defined and agreed to, you ll nail down the requirements quickly. The tests will help the programmers know when they are done and will help them avoid defects. Finally, running the tests will give the customer a concrete understanding of how things are going. Card, conversation, confirmation ”don t do software without them.
Daily builds are for wimps. (Extreme Programming, page xxix)
Most teams now realize that weekly or longer build cycles are a disaster ”the build always breaks. I once visited a team that was seven weeks behind on their weekly builds! Daily builds are a great improvement, but they only scratch the surface of what can and should be done. Many teams strike down with harsh consequences upon anyone who breaks the build. They are right to want the build not to break, but I suggest that it is a team issue, not a blame issue, when the build breaks. Stop the whole assembly line, figure out what went wrong, and fix the root cause.
Building many times per day is paradoxically easier than building once. First of all, the changes that can be made in an hour or two don t deviate as wildly as those saved up for a whole day or more, so an hourly build is much less likely to break. Second, if breaking the build is a team issue and we build many times per day, we will get very good at it. Those root causes of breaks will be discovered and corrected quickly.
Design all the time. (Chapter 1, page 8)
Design isn t something that we do just at the beginning of a project or story or task. As we work, we ll encounter design issues all the time, whether we re coding and find something awkward , testing and find something difficult to test, or even if we re just designing. If we can be sensitive to emerging design issues and respond to them immediately, the design will stay closer to good all the time.
Don t fall in love with our own work.
Sometimes we code up something really nifty and we re pretty proud of it. That s good ”it s important to practice and to exercise our skills. Sometimes we work really hard on something and finally get it to work. That s good too ” sometimes we have to get things done even if they aren t entirely pretty.
But both these situations, and others, can sometimes blind us to the fact that there s a better way to do whatever it is. When we feel ourselves resisting change, defending our code like it was our dearest child, it s more likely time to let go. Don t fight back. Pretend that someone else wrote that piece of junk, and get on board with seeing what s wrong with it and how to make it better. Then decide what to do.
End to end is further than you think. (Chapter 13, page 182)
When we test our product, we always try to test it from end to end. We want to make sure that inputs come in correctly, get processed correctly, and turn into outputs correctly. Paradoxically, it always seems that the worst problems occur just beyond the current edges of our testing. When this happens, there s not much we can do but push the ends out a bit further. I guess we just have to get used to it...
Expressing Intention . (Chapter 4, page 42)
We always have something in mind as we program, at least I hope we do. When we have finished something, often our intentions changed a bit along the way, as we learned what the code really wanted to do. Therefore, as we finish up some piece of code, let s look back at it, and at what we were trying to do, and see whether the code expresses that intention.
We have all had that joyful experience of reading some stretch of code and suddenly seeing what some part of it does: Look, this bit updates all the pending requests , then this bit selects one request, then the next bit processes that request! It s kind of fun to figure out that stuff, but it takes time and energy. Let s change the code to say what it does:
Request toDo = SelectNextRequest();
Sometimes it s even a good idea to program the intentions first and fill in the details later. We call both these practices Expressing Intention.
Fake it before you make it. Fake it till you make it. (Chapter 11, page 146)
In test-driven development, we do best when we cycle very quickly between writing a test and making it work. One way to speed up this cycle is to send a message to the object under test and, rather than write the code to return a fully robust answer, merely return a constant. Then we write a second test that requires us to fill in the details of the method. This practice seems odd to most people when they first encounter it, but many of us find it a useful approach, especially at the beginning of a new class or method. Give it a try!
Find a bug, write a test. (Chapter 5, page 58)
We don t want bugs in our code, right? We find bugs with tests, right? By writing tests, we prevent other people from embarrassing us by finding bugs, right? Therefore, if a bug is found, we have missed at least one test. Let s write it, think about it, and learn from it to write better tests in the future. And, as a useful side effect, when the new tests run, the bug is probably fixed!
Infrastructure doesn t please the customer; features do. (Chapter 30, page 472)
Of course, we can t do the program without infrastructure. Let s recognize, though, that building infrastructure is a necessary evil, and let s do it as frugally and incrementally as we possibly can. Unused infrastructure is a waste until it is used. Deleted features reduce customer happiness. Put these two facts together and build infrastructure incrementally, as needed, in support of features.
Isolate the unknown.
Often when we re working on something, we know how to do most of it and there s just this one part we don t know how to handle. Isolate that part, via one of two ways:
We can begin by focusing on that part, writing tests about it, programming it, and solving it. Now, since we understand the rest, everything is easy.
Or we can pretend that we know the solution, program as if it exists, and get the rest of the program laid out. Now we can focus on the unknown, and often doing what we know has made the unknown more clear.
It s Chet s fault. (Chapter 11, page 139)
Who broke the build is a common question but the wrong question. We all broke the build, through omission and commission. When a problem occurs, ask why, not who. To help with this, we have Chet. In the early days of Extreme Programming, the team was on a hunt to figure out who to blame for something. Chet Hendrickson stopped the meeting: Stop! It s my fault! Here, look, I m writing It s my fault on this card and signing it. From now on, everything is my fault. So, when you re wondering whose fault it is, now you know the answer: it s Chet s fault. Now get down to figuring out why it happened and what to do about it.
Keep the tests on green. (Chapter 17, page 213)
As I reflect back on this book, I can see that when my tests were good and all working except for one new one, things went rather well and I was relaxed and more productive. When my tests were weak or not running well, I was tense and less productive. I like relaxed and productive better. That s why I try to begin with a test and why I try to keep all the tests green.
Make it work; make it right; make it fast. (Chapter 17, page 215)
This might be the oldest advice in computing, except for Mr. Babbage, don t get your tie in the gears! I can t find the original source, but in any case it s good advice. First make the code get the right answers. Don t spend time honing or optimizing code that doesn t work yet. When it works, hone it to make it clean. Don t waste time optimizing code that is hard to understand. Then ” and only then ”if a performance test shows that this code is too slow, make it fast.
Outer design should drive inner design, always. (Chapter 30, page 473)
There s not much more irritating than programming with objects that aren t helping us. (See also Are the objects helping us? ) Tests are one good way to find out how easy or hard an object is to use. If it s hard to test, it s probably hard to use. Plus, it s often best to program top down, to better find out what the objects need to be.
Programming without thinking what good is that? (Chapter 30, page 473)
Sometimes it feels like we re just cranking out code by rote, almost without thinking about it. This can be a sign that what we re doing needs to be automated in some way, or perhaps we should ask, Are the objects helping us? If you re programming and not thinking about it, think about it.
Push a little when something seems too hard. (Chapter 17, page 216)
Sometimes I know what I should do, but it just seems too hard. When that happens, it s often valuable to push a bit. Sometimes I push myself to start on the difficult-seeming thing. Often once I get started, I can keep going. Other times I push on the idea of why it s hard. Dale Emery refers to Resistance as a Resource. When what we re doing is resisting us, there can be value in pushing back a bit. Of course, there can also be value in turning aside and going another way. I never said that all this would become obvious!
Reflect on how things are going. (Chapter 30, page 469)
It s good to pause frequently to see how we re doing ”another good reason to drink lots of fluids. Sit still for a moment, clear your mind, and pay attention to your body. Is it tense, uncomfortable in some way? Is your neck tight? Are you frowning? Is anything nagging at you? Is the code trying to tell you something? Are we on the right road, going in the right direction?
Removing duplication is your friend. (Chapter 11, page 151)
It s fascinating how valuable it is to observe and remove duplication in the code. Duplicate code represents some idea that is being used over and over. To remove it, we have to clarify that idea and give it a name and a place to be. The code gets better in small, smooth steps. Duplication can occur in space, in time, or in concept. Think about it, observe it, and mindfully remove it.
Solve what you know; leave the parts you don t know for later. (Chapter 6, page 78)
See also Isolate the unknown .
Some very simple refactoring has done most of the job for us. (Chapter 22, page 268)
Sometimes we get to a point where the solution we have been working on turns out to be wrong. Our reaction is often to start over on a new solution, but there is an alternative and it s often better. Parts of our bad solution might well be pretty good; otherwise , we wouldn t have been going that way. Consider refactoring the solution, extracting the good part from the bad or the bad from the good. In doing so, there s a good chance you ll tease apart the known from the unknown. Then just fix the part that needs it without wasting the good bits or doing them over.
Start a new path with something abysmally simple. (Chapter 4, page 45)
See also Fake it before you make it. Fake it till you make it. and What is the simplest thing that could possibly work? Do the simplest thing that could possibly work.
The story s not done until the customer tests run. (Chapter 6, page 72)
Use Customer Acceptance Tests ”the Confirmation part of a story ”as a means of communicating, but also as a means of feedback. Clearly, we can t call a story done until the tests run, but we should strive also to be done when the tests all run. If the tests run but some functionality still needs to be added, either the tests are incomplete or we re working on something that the customer doesn t want. If the tests run but there is still a lot of refactoring or cleanup to do, by all means do it, but try also to need only a little code to clean up before the code is ready to go. Refactoring works best in small doses all the time, not in big bites. Use the moment when the tests run as a time to see whether your refactoring is keeping up.
Twenty lines without a successful test is a pretty big change! (Chapter 4, page 45)
Except in rare circumstances, I think I probably write a defect every twenty lines, or at least every forty. Of course, it s an easy defect and after only a few console writes or a few moments in the debugger, I m back on track. On the other hand, I can almost always write five lines without a defect. How many lines should I write between successful tests?
Two Hats. (Chapter 8, page 95)
Kent Beck taught us to think of two hats: a new functionality hat and a refactoring hat. He told us to wear only one hat at a time, or we would look stupid. When we start refactoring in the middle of trying to make something work, we seem to make mistakes much more often. Add or fix functionality when the tests are red. Refactor or improve design when the tests are green. Are the hats themselves red and green? You decide. My hat is white.
We don t need a testing framework; we need tests. (Chapter 6, page 73)
Too often I see teams who have few customer tests because they are waiting until they (or QA) build a testing framework. If we have no tests, we don t know whether the program works. If we don t know whether the program works, it doesn t work. It s like driving with your eyes closed until you get sunglasses: a really bad idea. Don t wait for a framework ”write a test!
We start new features with large bold strokes. We re intentionally building from rough toward smooth. (Chapter 4, page 47)
You don t build fine furniture by taking triple-zero sandpaper to the nearest tree. The sequence is more like chain saw, band saw, circular saw, hand saw, coarse sandpaper, and finally the triple-aught. Consider coding the same way, first getting the big bits right and then refining and refining until everything is fitted just right. I think you ll save a lot of time, instead of polishing the wrong bits.
See also Make it work; make it right; make it fast.
What is the simplest thing that could possibly work? Do the simplest thing that could possibly work. (Chapter 28, page 408)
Often our first approach to a new problem is overly complex. We don t fully understand what we re up against, and we respond by figuring out a big solution or by fumbling around for hours with an ill-conceived idea. When he hears someone imagining a solution that may be too complex, Kent Beck likes to ask, What is the simplest thing that could possibly work? When we look at the problem this way, we often see a simpler approach that will get us started, or perhaps, even see us through.
For the past few years, in my own code, I ve been taking this idea a step further: I ask myself what the simplest thing is that could possibly work, and then I do it. I don t expect these solutions to hold up till the end of the application, although often they do. But because I try always to keep the shape of the code good, the simple solution is easy to improve later. Meanwhile, I m free to concentrate on the whole problem, by realizing this detail in a simple, albeit temporary way.
YAGNI ”You Aren t Gonna Need It. (Chapter 14, page 192)
We have all been there: We re coding away on something and we see the possibility for a neat generalization or a nifty feature. We don t really need it right now, but We re gonna need it ”might as well do it now. Extreme Programming suggests that you aren t gonna need it, but not because you aren t going to need it. Sometimes you will need it. We just automatically deny that we re gonna need it for a moment, because the issue really isn t the future ”the issue is now!
We don t need it now. If we write it now, it will lie unused for some period of time, until we do need it, if we ever do. Leaving aside whether we ever need it, and leaving aside whether it s just right for what we do finally need, face this: our investment of time in that neat feature is wasted until that future day when we put it into use, if in fact we ever do. Let s instead use our time now to make our customer happy, with another feature that she actually wants. That s not waste ”that s production.
But, you protest, it ll be easier and cheaper to put in now.
We figure the code we ll put in now will be the right code later? I ask. You assure me that it will.
So, if we wait, we ll just have to put that same code in there after all?
Yes, you tell me.
Well, I ask, if it s the same code, why will it be harder later than it is now? You glare at me for a while and then try, But I know how to do it now, and I ll have to figure it out again later.
So, the code we have now is hard to understand? Maybe we should focus on that instead of this new feature?
Well, probably at this point you kill me, which makes me glad this is a book and not a meeting. But my point remains: it should not be cheaper now than later, and, if it is, we should address that issue, not the new feature.
Now of all the points in this book, this may be the hardest to accept, so in a way I m glad it s at the end of this list. I hope you believe me, but I m not asking you to take it on faith. Instead, I m asking this: When you have one of those ideas and you decide to go ahead and do it, pay attention to what happens. How long does it take to do; does it get used; how long is it until it is used; how close to right is it when it does get used; and how hard does it look to do if you had to do it at that point?
And sometimes, when you have one of those ideas, make note of it, but don t put it in. See whether the time comes when you do need to do it and how hard it is to do at that later time. Adjust your balance as your own experience dictates, and maybe drop me a note about what you learned.