The design strategy in XP is to create the simplest design that meets your current requirements, as reflected in the
current test cases. In many domains, "simplest design" is ambiguous, but it is a well-defined term in XP. A simple
design has these four characteristics, listed in priority order:
The system runs all the tests.
It contains no duplicate code.
The code states the programmers's intent very clearly.
It contains the fewest possible number of classes and methods.
Design in Extreme Programming is much more incremental than in any other methodology. The practice of Test-Driven
Development describes how the system is created in many small steps, driven by tests that programmers write. Each of
these tests is a probe into the design of the system, allowing the developers to explore the system as it is being
created. This is quite a contrast to other methodologies where design is a separate phase of either the project or the
iteration. In XP, design quite literally happens all the time.
It takes a tremendous amount of courage to stop designing and start coding. Almost all developers are taught that they
should understand everything about the system before committing that knowledge to code. The reason, they've always been
told, is that code is hard to change. Once it is laid on its virtual paper, changing it involves understanding the
hidden assumptions of the original developer, unseen couplings, months-long validation and verification procedures,
etc. But if code could be changed with impunity, developers could afford to defer design decisions until later,
understand the system incrementally, and implement in pieces.
The strategy of building software in this manner is based on the following reasoning:
Given that all requirements aren't known on the first day of the project, the development style must be adjusted to
accommodate new understanding from customers and changes in the business climate.
If a design decision does not have to be made now, avoid guessing by deferring the decision until it is needed. By
that time, there is a better chance that enough understanding will exist to support a better decision.
Change happens during the lifetime of a project. Decisions made once will be changed. The software must be designed
and implemented in such a way that changes can be accommodated easily.
Designs seldom survive their first skirmish with code. The act of coding provides feedback to the developer about
the system. This learning must be reflected in the design. If the design is already cast before coding begins, this
feedback is more difficult and costly to put back into the design.
Here are some guidelines to help in arriving at a simple design:
Look for a simple way to solve a problem. Software is hard, so there will be plenty of time for complexity later.
For now, keep it simple. Simple, however, does not mean stupid. Pay attention to good design principles when
forming a system incrementally.
Resist the temptation to add infrastructure or other features that might be needed later. Chances are they won't be
(YAGNI: You Aren't Going to Need It). Let the user stories force you to change the design.
Don't generalize a solution until it is needed in at least two places. Follow the first rule above and keep
implementation simple. Let the second user pay for the generality.
Seek out and destroy duplication. The practice of Refactoring is the most powerful tool in the arsenal. It is through removing
duplication that new classes, methods, and larger scale systems are born.
Remember that it is just code. If it is getting overly complex and painful, delete it. It can always be recreated
again in less time and better than the first time by leveraging what was learned the first time.
Small initial investment: There is no need to invest in frameworks or generality that might be or might not
be required in the future.
Maintainability: Simple design will keep the design from rotting and dying prematurely. The more complex the
design is, the harder it is to understand and preserve and the more rapidly it will decay.
Flexibility: Simple systems are always easier to change than more complex systems.
Agility: Simple systems are faster to change than more complex systems.