| Extreme Programming Explained |
| Kent Beck Addison Wesley, 2000 |
Summary
Extreme Programming (XP) is a new methodology for software development: in part it builds on standard programming principles but in other areas it challanges orthodoxy. It is this challange to the norm that makes XP such an exciting read, it is constantly asking the reader to question their assumptions and re-consider things they perhaps believed to be self-evident. Whether you agree with it or not, it is certainly useful for anyone concerned with developing software to at least be aware of the arguments of XP. Kent Beck the author of the book invented XP, so he must be the authority on it. This is his introduction to it, from page XV:
Why "extreme" in the name? XP takes commonsense principles and practises to extreme levels:
- If code reviews are good, we'll review code all the time (pair programming).
- If testing is good, everybody will test all the time (unit testing), even the customers (functional testing).
- If design is good, we'll make it part of everybody's daily business (refactoring).
- If simplicity is good, we'll always leave the system with the simpliest design that supports its current functionality (the simpliest thing that could possibly work).
- If architecture is important, everybody will work defining and refining the architecture all the time(metaphor).
- If integration is important, then we'll integrate and test several times a day (continuous integration).
- If short iterations are good, we'll make the iterations really, really short - seconds and minutes and hours, not weeks and months and years (the Planning Game).
Introduction
Extreme Programming is a lightweight methodology combining the now 'standard' principles of
- release early, release often
- give responsibility to the programmers: think "people"
- keep sane working hours
- don't duplicate
- work with use cases, keep a flexible implementation
with more radical/extreme ideas of
- pair programming - always program in pairs;
- continual testing - run tests whenever you change any code to ensure it still works;
- continual integration - continually integrate the code into a full product build.
In the middle of this are ideas which seem sensible, but perhaps aren't 'standard'.
- Keep things simple - don't design for re-use because you don't know how you will re-use something, only implement what you need to implement today, and if you need to extend it in the future, fine - do so then.
- Regularly "refactor" the code - make it simple and clean. This means as part of development, if you come across something that has been done in a complex manner, re-write it to keep it simple.
- Everyone has access to all the code. If you come across something you think could be done better, do it.
- Throw-away code. If you've done something poorly, throw it away and do it better.
- Use "To Do" cards to keep a list of programming tasks outstanding. ("Toss the code and start again", p.33)
Other points made, in no particular order:
- Give programmers fast feedback - this is how they learn. Make sure there is a tight feedback loop for estimating, so they can continually refine their skill in estimating.
- Include the customer in the development team.
- When planning development,
- Identify risk and investigate this at the start of the project. Programmers need to 'explore' to be sure that any unknowns are removed at the start of development.
- Implement the most important things from a business point of view first, so if the project slips and scope is changed, the important items will be completed.
- The cost of change is low or flat. This challanges the assumption that the cost of change rises as development progresses. Instead it is argued that with current development tools it is not particularly expensive to make a change during development instead of getting it right in the planning stage first.
- Don't estimate lower than you know. Don't say something will take 17 hours if your best guesses are in days.
- Don't document the code - or not in detail. Documentation means you will forever be trying to keep the documentation and the code in sync. If the code is simple, it will be ok without documentation, however if you stop working on it, write a few pages summarising how it works.
First Impressions
After reading the book, the following thoughts come to mind:
Pair programming. This is perhaps the most radical idea of XP. The first thought is: won't this half my productivity? Aren't you going to have two developers working at the rate of one? However against this, one could argue:
- If you have ever worked like this - even for a short while - it is an extraordinary experience, one programmer is constantly checking the quality of the work of the other, whilst also thinking ahead and considering other issues. It certainly feels as if two could be productive.
- The code will be better quality - not only is the second programmer watching for silly mistakes, they are also able to think about the general design and implementation while the other person codes. In theory this should lead to the other programmer suddenly wanting to "take over" because they have thought about how to do the next stage, so there shouldn't be any pauses while one programmer thinks about what to do next.
- If you think about when you take a break from programming you often think of a better or smarter way to do something. With two programmers, the one watching has this "break" in that they don't have their head full of code, they can think better how to keep the implementation neat and simple.
- You don't just sit and code, you stop and think. While one person is coding the other is thinking, so when the first programmer finishes their section the second can kick off with their ideas.
- There is continual "peer pressure" to code to a high standard. If someone is watching you, you don't take short-cuts or "hacks".
- There is little opportunity to avoid standards, skip tests or avoid stepping through code with someone else there.
- In terms of productivity, while it seems mathematically unlikely that two could code as quick as two programmers working separately, it seems reasonable to assume that the quality of code would be much higher, resulting in less re-work and bug fixing. Hence overall the productivity may not be much behind two programmers working separately.
- There is no code that only one programmer knows, and so is "their" code. No one is "in charge" of a section of code, at least two programmers know any bit of code written, hence maintenance and further development is less tied to a single developer for that section of code.
- There is more sharing of skills and knowledge, because each programmer learns skills from the other. This again could improve productivity. It is also a good way for a programmer to join a team.
- Less supervision is required - again there is less risk when taking on new developers.
- There could be problems if people don't get on and so don't work well together.
- Two people working together could provide a distraction for each other by discussing non-work related topics.
Considering continual testing and continual integration, this issue seems far more complex. Much of XP works on the assumption that this can happen:
- You can only regularly re-factor code when you come across complex code if you are able to easily re-run tests to check if what you have changed still works.
- You can only give full-access to all the code (no code 'owners') if anyone who makes a change can re-run tests to confirm their changes haven't broken something.
However making tests run automatically with visual interfaces and SQL databases is non-trivial, and potentially they will (a) take a long time to run, (b) take a long time to write, and (c) be fragile to changes in the software and so require significant maintenance to keep up to date. It would be interesting to see how easy such testing is in practise on a large, SQL, GUI application.
Continual integration asks the same questions. Even if you identified the set of tests to run against your code - and again it may not be simple to identify which tests are associated with work area of code - there are typically different versions, different configurations, different platforms supported, different international versions etc. So again, how much testing can quickly be done when you change an area of code?
Regarding the questions of changing scope - to have a very loose framework in which a few "stories" are implemented and things change as work progresses - seems to raise questions about how a customer would pay for such work. Would they pay for development time, and "buy" what is ready when the time is elapsed? How could such a system get a budget justified? There seems no correspondence between requirements and what is delivered. To continually allow a customer to change their requirements without proper change control seems to invite problems over what a software company is contracted to deliver when they win a software contract.
On keeping a customer on a project - this is clearly useful in many cases where the implementation detail has not been clearly agreed beforehand. Of course there any many times during development that a programmer has to make a decision on how a feature should be implemented, and perhaps there should be a customer on hand to advise in all these cases. However against this is the cost of having someone no longer doing their normal work for which they were employed and instead joining the development team, there is the question as to how representative they are of the other members of their team, could they keep changing their minds and so prevent development progressing? How much power have their to affect the project schedule, could they change the detail of the implementation if this impacted the project schedule? I would agree that a customer should be available for developers to contact if they have questions about implementation, and that customers should review the project at regular milestones, but am not convinced about joining the project team.
Regarding the flat cost of change - I just don't see how you can generalise on this. True, there are some cases where it is silly to "guess" how something will be implemented in the future, and "half" implement it today. In those cases I agree that the "guess" as to how something will be implemented is bound to fail - you never spend the time required to plan a good design and so only end up totally undoing how you imagined something would be implemented and re-doing it again anyway. However that doesn't mean there is a flat cost to any change. There are at least three points to make:
- certain principles of implementation make change easier - in OO hiding implementation, in C and C++ hiding data types - changing all ints to chars for a particular data item is much more costly to change part-way through implementation if you haven't hidden the data type (and sometimes even if you have hidden it but made assumptions on the native type used).
- changing relationships between objects can be costly. If you originally only planned to have a one-to-one relationship and now want to change to a one-to-many or evenmany-to-many it will have been far cheaper to have realised this would be required at the start of development, rather than changing part-way through.
- Decisions such as programming language to use, OS to use, database to use etc all need to be made at the start and are costly to change later.
Other Ideas Noted
Metrics - keep important metrics on the wall if people aren't doing something - it will act as a "gentle reminder".
Estimating:
- Always estimate first in "ideal" engineering time, if an engineer was working solid on something, then add the "velocity", this is ideal engineering time versus calendar time.
- List which items you can estimate, which you are not sure about (risks) and which you just can't estimate.
- Keep a short timescale for re-estimating, every few days. Use load factors as a percentage of actual time programming, for example new team members 2 or 3 days out of 15, others 7 or 8 days out of 15.
- How long does planning and estimating actually take? The book refers to "only having a week to plan" meaning spending a whole week just planning a project. Is this typical? How long is typically spent planning verses time spent on the project? (see page 95).
- "If integration took a couple of hours it would not be possible to work in this style" (p.98), surely most software projects take a couple of hours at minimum to integrate code into a configuration?
- Using charts and pictures in design and planning: "never spend more than 15-20 minutes on pictures" (p.112)
XP Fears and non-fears
Kent Beck says at the end of the book:
To the degree that XP is my baby it reflects my fears, I am afraid of:
- Doing work that doesn't matter
- Having projects cancelled because I didn't make enough technical progress
- Making business decisions badly
- Having business people make technical decisions badly for me
- Coming to an end of a career building systems and realising that I should have spent more time with my kids
- Doing work I'm not proud of
XP also reflects the things I'm not afraid of:
- Coding
- Changing my mind
- Proceeding without knowledge of everything in the future
- elying on other people
- Changing the analysis and design of a running system
- Writing tests
©John Mann, 2000