Yes, extreme programming works surprisingly well. We did not adopt all practices at once, but after a year, most practices became second nature to everyone in our group.
The early book "Extreme Programming Explained" by Kent Beck, is the best introduction. See also http://www.extremeprogramming.org/ and http://www.xprogramming.com/. I found two more books essential before we began the two-week iteration planning game: "Planning Extreme Programming" by Beck and Fowler, and "Extreme Programming Installed" by Jeffries et al.
First we adopted continuous builds and tests: they are the foundation of everything else. We perform a clean build of the system and run all the tests about once an hour during the day, in addition to nightly builds (which we have done for years). As we edit code, we modify tests and run them frequently, to catch errors before we forget the cause. After a while, you find yourself writing the test first. You find yourself wanting tests before you have courage to add the next new feature.
The trick to testing GUI code is to make sure the models and views are well-separated. Event handlers should be delegate all intelligent decisions to non-GUI classes. If you test the non-GUI code, the GUI will take care of itself.
See more on unit tests here: [ Unit_Tests.html ] .
Before checking any code into our CVS repository, we run all the tests with our local working copy. After checking in code, we relaunch a clean rebuild and test of the system on a build machine. If any test fails, the build has failed. Our policy is that no compilation should be broken over an hour and no test should fail overnight. Otherwise, the offending party should undo the checkins.
Next, we had users trying to use the code constantly, and ensured that we implemented features they cared about first. This encouraged us also to "do the simplest thing that could possibly work" and save enhancements for later, when the users might or might not want them. Because users concentrated on different parts of the product at different times, it was necessary for every developer to learn more about the entire system. (Many projects move to iterative development during bug fixing: [ Moving_to_iterative_development.html ] )
Quickly, we adopted the idea that no one owns any code. No code should be trusted until at least two coders feel able to maintain it.
Anyone should feel safe at any time to get updates from the repository. Changes to code should be small. Anytime a useful enhancement is made, we check it in, even if only a few lines have changed. We update our working copies from the repository many times each day. I try to go home at the end of the day without any unfinished work remaining outside of the repository.
See more justification for simplicity here: [ Unused_generality_makes_code_hard_to_modify.html ]
Constant refactoring is essential. See "Refactoring" by Martin Fowler from Addison Wesley for an excellent demonstration of how most any complicated refactoring can be broken into small safe steps. You don't have to finish any refactoring if you don't trust the next step. Only thorough tests make this possible. Writing tests saves time.
See more on refactoring here: [ Refactoring_is_not_rewriting.html ]
Throughout, we tried programming in pairs, particularly when we were in a hurry. We still program in pairs less than half the time. No one is dragged into it. But pair programming works. We get much more done, and the code looks better than either could have written alone. See more on pair programming here: [ Pair_Programming.html ]
Finally, we adopted a formal 2-week iteration cycle. Managers actually love it because our progress is completely transparent. We can easily prepare reports of our priorities and progress. We got very good at predicting how long any new features will take. Programmers love it because our work is highly visible (without paperwork) and because we know we're always working on something someone actually wants. See more on project management here: [ How_can_programmers_improve_project_management.html ]
Bill Harlan, 2001
Return to parent directory.