May 1, 2000
There is a major disconnect between theory and reality in the world of software development.
In the world of theory, all requirements are specified up front, and customers do not change them. Management gives everyone plenty of time to do analysis and design. During the implementation phase, if the code gets too brittle due to too many changes, ample time is provided to rewrite it in its entirety. When it comes to testing, the programmers will not rest until every bug is fixed, no matter how long this takes. At last the customer gets the product, and it is exactly what they need to make their lives easier and more productive. Moreover, it is easy to learn and use, because of the extensive analysis and reviews we conducted eons ago when the project first started.
A belief in this ideal world is the underpinning for almost every text written about software process. Sometime the authors admit that all is not rosy, and use variations like iterations and change management to accommodate the unpleasant fact that the world they are describing does not exist. The sad thing is that so many teams have followed the prescriptions offered, yet their projects fail, and they are left wondering what they did wrong.
There is a growing concern that our current approach to software development is fundamentally flawed. Some of the brightest people in the field are rethinking all of the old assumptions, and coming up with new ideas that are more suitable for tackling the challenges that a modern programming team faces. This exciting new movement is known as Extreme Programming, or XP, and it could eventually change the way we go about the business of creating new software.
Extreme Programming is not about descending into chaos, leaving all discipline behind. Nor does it advocate a disregard for good analysis and design. Rather, it is all about doing things in the most efficient manner possible, balancing the conflicting desire to finish a product on time while producing code of acceptable quality.
Most projects suffer from one or more of the following problems:
Gathering all the requirements for a project up front is nearly impossible. Customers often do not know what they want, and they frequently change their mind as the project progresses.
Designing an entire system before a line of code is written is very challenging. Only a few people can pull it off without having to modify their initial design. Unfortunately, such design modifications eventually lead to a code base that is brittle and unstable.
Projects run out of money or get cancelled. Usually when this happens, nothing usable can be salvaged.
There is no time to do a rewrite. Even when the team knows that the code base is unstable and needs to be rewritten, the project schedule will not allow it.
Not everyone writes good code. Most teams have a combination of outstanding programmers and mediocre ones, yet the overall code quality needs to be consistent.
Testing does not catch every problem. For most projects, the testing is done at the end, and there is usually not enough time to find and fix all the defects. Moreover, fixing a bug can cause new bugs to crop up, leading to a situation where converging on stable code may be hard or impossible to do.
Extreme Programming is a holistic approach. It prescribes a series of practices that, when taken together, can help solve the problems most projects face. Each practice alone has its weaknesses, but these are balanced by the strengths in the other practices.
The practices are:
I briefly explain each below, along with its potential problems and the remedies to these problems.
There is always a conflict between Business and Development. By establishing a few simple rules, the needs of each can be balanced out. Business decides what features are the most crucial. Development decides how long they will take to implement. Then Business either chooses the features they want and accepts the date given by the estimates, or chooses the date they want and accepts the features that can be done within this time. Then Development produces a detailed plan for the first release, and then goes off and produces it. The process is then repeated, with an updated plan a new release. In this way Business gets what they really want, and Development is given a task it can complete in a timely manner. And because the plan is updated fairly frequently, it is a reasonable reflection of what Business needs and what Development can do.
The development team puts together a working, useful release as soon as possible, and then continues to release new versions very frequently. This provides a working system for the customer as soon as possible, which allows them to play with the system and identify what needs to be changed. Furthermore, getting something they can actually use right away builds up the customer's trust in the development process.
A metaphor is an informal, yet concise, description of how the system should operate and what it needs to accomplish. It provides a focal point for the team, and is a source for consistent terminology when referring to parts of the system or the functions it can perform.
Always design for what you need today, because you really cannot anticipate what you will need tomorrow. This way your design is always as simple as it can be, which makes understanding and testing the system much easier.
All parts of the system that could conceivably break are protected with unit tests. These tests are run whenever a change is made to the affected code.
In addition, the customer defines a series of functional tests that define how the system is supposed to behave. The system will not be released until these tests pass.
When a programmer is about to make a change, they look at the code to see if the change will be easy to add in, given the design of the system. If it is not, then they improve and simplify the design until the change is easy to make. Only then do they make the change.
This provides two advantages. One is that the design is continually improved. Two is that no changes are just "hacked in".
All programming of production code is done by two people. One sits at the keyboard and codes, the other looks on and provides advice, corrects mistakes, etc. When one gets tired, they either switch or take a break.
All code written is the property of the team, and not of an individual or a pair. If someone sees a problem in some code, they should go ahead and fix it, whether they wrote it or not. This way no one waits around for someone else to fix a problem, and the whole team has a good overall knowledge of the code base.
This is simple. No one works overtime, because tired programmers get cranky and make mistakes, and thus the net amount of useable code is not raised by upping the number of work hours.
If you are going to build a system for a customer, you need someone that represents that customer to be available to the programmers to answer questions, help design functional tests, and generally participate in the development process whenever appropriate. The ideal scenario is to have them available at all times, in order to keep the process moving as quickly and efficiently as possible. The best way to do this is to have the customer on-site.
Pair programming, refactoring, and collective ownership are too difficult to do if everyone uses a different coding style. By adhering to a simple set of coding standards, the team can be more efficient. Furthermore, the whole body of code will have a uniform appearance, which will enhance its maintainability.
I have just touched on the very basics of XP. I recommend that everyone read the book Extreme Programming Explained [Beck] for a much more detailed (and fascinating) description of this new discipline.
Beck, Kent (2000). Extreme Programming Explained. Reading, MA: Addison Wesley Longman Inc.
Fowler, Martin (1999) Refactoring. Reading, MA: Addison Wesley Longman Inc.