Predictive versus Adaptive (Courtesy
of Martin Fowler)
Separation of Design and
Construction
The usual inspiration for methodologies is engineering disciplines such as
civil or mechanical engineering. Such disciplines put a lot of emphasis on
planning before you build. Such engineers will work on a series of drawings
that precisely indicate what needs to be built and how these things need to be
put together. Many design decisions, such as how to deal with the load on a
bridge, are made as the drawings are produced. The drawings are then handed
over to a different group, often a different company, to be built. It's assumed
that the construction process will follow the drawings. In practice the
constructors will run into some problems, but these are usually small.
Since the drawings specify the pieces and how they need to be put together,
they act as the foundation for a detailed construction plan. Such a plan can
figure out the tasks that need to be done and what dependencies exist between
these tasks. This allows for a reasonably predictable schedule and budget for
construction. It also says in detail how the people doing the construction work
should do their work. This allows the construction to be less skilled
intellectually, although they are often very skilled manually.
So what we see here are two fundamentally different activities. Design which is difficult to predict and requires expensive
and creative people, and construction which is easier to predict.
Once we have the design, we can plan the construction. Once we have the plan
for the construction, we can then deal with construction in a much more
predictable way. In civil engineering construction is much bigger in both cost
and time than design and planning.
So the approach for software engineering methodologies looks like this: we
want a predictable schedule that can use people with lower skills. To do this
we must separate design from construction. Therefore we need to figure out how
to do the design for software so that the construction can be straightforward
once the planning is done.
So what form does this plan take? For many, this is the role of design
notations such as the UML. If we can
make all the significant decisions using the UML, we can build a construction
plan and then hand these designs off to coders as a construction activity.
But here lies the crucial question. Can you get a design that is capable of
turning the coding into a predictable construction activity? And if so, is cost
of doing this sufficiently small to make this approach worthwhile?
All of this brings a few questions to mind. The first is the matter of how
difficult it is to get a UML-like design into a state that it can be handed
over to programmers. The problem with a UML-like design is that it can look
very good on paper, yet be seriously flawed when you actually have to program
the thing. The models that civil engineers use are based on many years of
practice that are enshrined in engineering codes. Furthermore the key issues,
such as the way forces play in the design, are amenable to mathematical
analysis. The only checking we can do of UML-like diagrams is peer review.
While this is helpful it leads to errors in the design that are often only
uncovered during coding and testing. Even skilled designers, such as I consider
myself to be, are often surprised when we turn such a design into software.
Another issue is that of comparative cost. When you build a bridge, the cost
of the design effort is about 10% of the job, with the rest being construction.
In software the amount of time spent in coding is much, much less McConnell suggests
that for a large project, only 15% of the project is code and unit test, an
almost perfect reversal of the bridge building ratios. Even if you lump in all
testing as part of construction, then design is still 50% of the work. This
raises an important question about the nature of design in software compared to
its role in other branches of engineering.
These kinds of questions led Jack Reeves to suggest
that in fact the source code is a design document and that the construction
phase is actually the use of the compiler and linker. Indeed anything that you
can treat as construction can and should be automated.
This thinking leads to some important conclusions:
- In software: construction is
so cheap as to be free
- In software all the effort
is design, and thus requires creative and talented people
- Creative processes are not
easily planned, and so predictability may well be an impossible target.
- We should be very wary of
the traditional engineering metaphor for building software. It's a
different kind of activity and requires a different process
The Unpredictability of
Requirements
There's a refrain I've heard on every problem project I've run into. The
developers come to me and say "the problem with this project is that the
requirements are always changing". The thing I find surprising about this
situation is that anyone is surprised by it. In building business software
requirements changes are the norm, the question is what we do about it.
One route is to treat changing requirements as the result of poor
requirements engineering. The idea behind requirements engineering is to get a
fully understood picture of the requirements before you begin building the
software, get a customer sign-off to these requirements, and then set up
procedures that limit requirements changes after the sign-off.
One problem with this is that just trying to understand the options for
requirements is tough. It's even tougher because the development organization
usually doesn't provide cost information on the requirements. You end up being
in the situation where you may have some desire for a sun roof on your car, but
the salesman can't tell you if it adds $10 to the cost of the car, or $10,000.
Without much idea of the cost, how can you figure out whether you want to pay
for that sunroof?
Estimation is hard for many reasons. Part of it is that software development
is a design activity, and thus hard to plan and cost. Part of it is that the basic
materials keep changing rapidly. Part of it is that so much depends on which
individual people are involved, and individuals are hard to predict and
quantify.
Software's intangible nature also cuts in. It's very difficult to see what
value a software feature has until you use it for real. Only when you use an
early version of some software do you really begin to understand what features
are valuable and what parts are not.
This leads to the ironic point that people expect that requirements should
be changeable. After all software is supposed to be soft.
So not just are requirements changeable, they ought to be changeable. It takes
a lot of energy to get customers of software to fix requirements. It's even
worse if they've ever dabbled in software development themselves, because then
they "know" that software is easy to change.
But even if you could settle all that and really could get an accurate and
stable set of requirements you're probably still doomed. In today's economy the
fundamental business forces are changing the value of software features too
rapidly. What might be a good set of requirements now, is not a good set in six
months time. Even if the customers can fix their requirements, the business
world isn't going to stop for them. And many changes in the business world are
completely unpredictable: anyone who says otherwise is either lying, or has
already made a billion on stock market trading.
Everything else in software development depends on the requirements. If you
cannot get stable requirements you cannot get a predictable plan.
Is Predictability Impossible?
In general, no. There are some software
developments where predictability is possible. Organizations such as NASA's
space shuttle software group are a prime example of where software development
can be predictable. It requires a lot of ceremony, plenty of time, a large
team, and stable requirements. There are projects out there that are space
shuttles. However I don't think much business software fits into that category.
For this you need a different kind of process.
One of the big dangers is to pretend that you can follow a predictable
process when you can't. People who work on methodology are not very good at
identifying boundary conditions: the places where the methodology passes from
appropriate in inappropriate. Most methodologists want their methodologies to
be usable by everyone, so they don't understand nor publicize their boundary
conditions. This leads to people using a methodology in the wrong
circumstances, such as using a predictable methodology in a
unpredictable situation.
There's a strong temptation to do that. Predictability is a very desirable
property. However if you believe you can be predictable when you can't, it
leads to situations where people build a plan early on, then don't properly
handle the situation where the plan falls apart. You see the plan and reality
slowly drifting apart. For a long time you can pretend that the plan is still
valid. But at some point the drift becomes too much and the plan falls apart.
Usually the fall is painful.
So if you are in a situation that isn't predictable you can't use a
predictive methodology. That's a hard blow. It means that many of the models
for controlling projects, many of the models for the whole customer relationship,
just aren't true any more. The benefits of predictability are so great, it's difficult to let them go. Like so many problems
the hardest part is simply realizing that the problem exists.
However letting go of predictability doesn't mean you have to revert to
uncontrollable chaos. Instead you need a process that can give you control over
an unpredictability. That's what adaptivity is all
about.
Controlling an
Unpredictable Process - Iterations
So how do we control ourselves in an unpredictable world? The most important, and still difficult part is to know accurately
where we are. We need an honest feedback mechanism which can accurately tell us
what the situation is at frequent intervals.
The key to this feedback is iterative development. This is not a new idea.
Iterative development has been around for a while under many names:
incremental, evolutionary, staged, spiral... lots of names. The key to
iterative development is to frequently produce working versions of the final
system that have a subset of the required features. These working systems are
short on functionality, but should otherwise be faithful to the demands of the
final system. They should be fully integrated and as carefully tested as a
final delivery.
The point of this is that there is nothing like a tested, integrated system
for bringing a forceful dose of reality into any project. Documents can hide
all sorts of flaws. Untested code can hide plenty of flaws. But when people
actually sit in front of a system and work with it, then flaws become truly
apparent: both in terms of bugs and in terms of misunderstood requirements.
Iterative development makes sense in predictable processes as well. But it
is essential in adaptive processes because an adaptive process needs to be able
to deal with changes in required features. This leads to a style of planning
where long term plans are very fluid, and the only stable plans are short term
plans that are made for a single iteration. Iterative development gives you a
firm foundation in each iteration that you can base
your later plans around.
A key question for this is how long an iteration
should be. Different people give different answers. XP suggests iterations of
one or two weeks. SCRUM suggests a length of a month.
The Adaptive Customer
This kind of adaptive process requires a different kind of relationship with
a customer than the ones that are often considered, particularly when
development is done by a separate firm. When you hire a separate firm to do
software development, most customers would prefer a fixed-price contract. Tell
the developers what they want, ask for bids, accept a bid, and then the onus is
on the development organization to build the software.
A fixed price contract requires stable requirements and hence a predictive
process. Adaptive processes and unstable requirements imply you cannot work
with the usual notion of fixed-price. Trying to fit a fixed price model to an
adaptive process ends up in a very painful explosion. The nasty part of this
explosion is that the customer gets hurt every bit as much as the software
development company. After all the customer wouldn't be wanting some software
unless their business needed it. If they don't get it their business suffers.
So even if they pay the development company nothing, they still lose. Indeed
they lose more than they would pay for the software (why would they pay for the
software if the business value of that software were less?)
So there's dangers for both sides in signing the traditional fixed price contract
in conditions where a predictive process cannot be used. This means that the
customer has to work differently.
This doesn't mean that you can't fix a budget for software up-front. What it
does mean is that you cannot fix time, price and scope. The usual agile
approach is to fix time and price, and to allow the scope to vary in a
controlled manner.
In an adaptive process the customer has much finer-grained control over the
software development process. At every iteration they
get both to check progress and to alter the direction of the software
development. This leads to much closer relationship with the software
developers, a true business partnership. This level of engagement is not for
every customer organization, nor for every software developer; but it's
essential to make an adaptive process work properly.
All this yields a number of advantages for the customer. For a start they
get much more responsive software development. A usable, although minimal,
system can go into production early on. The customer can then change its
capabilities according to changes in the business, and also from learning from
how the system is used in reality.
Every bit as important as this is greater visibility into the true state of
the project. The problem with predictive processes is that project quality is
measured by conformance to plan. This makes it difficult for people to signal
when reality and the plan diverge. The common result is a big slip in the
schedule late in the project. In an agile project there is a constant reworking
of the plan with every iteration. If bad news is
lurking it tends to come earlier, when there is still time to do something
about it. Indeed this risk control is a key advantage of iterative development.
Agile methods take this further by keeping the iteration lengths small, but
also by seeing these variations in a different way. Mary Poppendieck
summed up this difference in viewpoint best for me with her phrase "A
late change in requirements is a competitive advantage". I think most
people have noticed that it's very difficult for business people to really
understand what they need from software in the beginning. Often we see that
people learn during the process what elements are valuable and which ones
aren't. Often the most valuable features aren't at all obvious until customer
have had a chance to play with the software. Agile methods seek to take
advantage of this, encouraging business people to learn about their needs as
the system gets built, and to build the system in such a way that changes can
be incorporated quickly.
All this has an important bearing what constitutes a successful project. A
predictive project is often measured by how well it met its plan. A project
that's on-time and on-cost is considered to be a success. This measurement is
nonsense to an agile environment. For agilists the
question is business value - did the customer get software that's more valuable
to them than the cost put into it. A good predictive project will go according
to plan, a good agile project will build something different and better than
the original plan foresaw.