At the very beginning of a project, you and the team need to learn the
requirements. Simply being told what to do or
listening to users is not enough: read Topic 45, The Requirements Pit and learn how to avoid the common traps and pitfalls.
Conventional wisdom and constraint management are the topics of
Topic 46, Solving Impossible Puzzles. Whether you are performing
requirements, analysis, coding, or testing, difficult problems will crop
up. Most of the time, they won't be as difficult as they first appear
to be.
And when that impossible project comes up, we like to turn to our secret weapon: Topic 47, Working Together. And by “working together” we don't mean sharing a massive requirements document, flinging heavily cc'd emails or enduring endless meetings. We mean solving problems together while coding. We'll show you who you need and how to start.
Even though the Agile Manifesto begins with “Individuals and interactions over processes and tools,” virtually all “agile” projects begin with an ironic discussion of which process and which tools they'll use. But no matter how well thought out it is, and regardless of which “best practices” it includes, no method can replace thinking. You don't need any particular process or tool, what you do need is the Topic 48, The Essence of Agility.
With these critical issues sorted out before the project gets under
way, you can be better positioned to avoid “analysis paralysis” and
actually begin—and complete—your successful project.
Topic 45. The Requirements Pit
Perfection is achieved, not when there is nothing left to add but when there is nothing left to take away...
Antoine de St. Exupery, Wind, Sand, and Stars, 1939
Many books and tutorials refer to requirements gathering as an early
phase of the project. The word “gathering” seems to imply a tribe of
happy analysts, foraging for nuggets of wisdom that are lying on the
ground all around them while the Pastoral Symphony plays gently in the
background. “Gathering” implies that the requirements are already
there—you need merely find them, place them in your basket, and be
merrily on your way.
It doesn't quite work that way. Requirements rarely lie on the
surface. Normally, they're buried deep beneath layers of assumptions,
misconceptions, and politics. Even worse, often they don't really exist
at all.
Tip 75: No One Knows Exactly What They Want
The Requirements Myth
In the early days of software, computers were more valuable (in terms of
amortized cost per hour) than the people who worked with them. We saved
money by trying to get things correct the first time. Part of that
process was trying to specify exactly what we were going to get the
machine to do. We'd start by getting a specification of the
requirements, parlay that into a design document, then into flowcharts
and pseudo code, and finally into code. Before feeding it into a
computer, though, we'd spend time desk checking it.
It cost a lot of money. And that cost meant that people only tried to
automate something when they knew exactly what they wanted. As
early machines were fairly limited, the scope of problems they solved
was constrained: it was actually possible to understand the whole
problem before you started.
But that is not the real world. The real world is messy, conflicted, and
unknown. In that world, exact specifications of anything are rare, if
not downright impossible.
That's where we programmers come in. Our job is to help people
understand what they want. In fact, that's probably our most valuable
attribute. And it's worth repeating:
Tip 76: Programmers Help People Understand What They Want
Programming as Therapy
Let's call the people who ask us to write software our clients.
The typical client comes to us with a need. The need may be strategic,
but it is just as likely to be a tactical issue: a response to a current
problem. The need may be for a change to an existing system or it may
ask for something new. The need will sometimes be expressed in business
terms, and sometimes in technical ones.
The mistake new developers often make is to take this statement of need
and implement a solution for it.
In our experience, this initial statement of need is not an absolute
requirement. The client may not realize this, but it is really an
invitation to explore.
Let's take a simple example.
You work for a publisher of paper and electronic books. You're given a
new requirement:
Shipping should be free on all orders costing $50 or more.
Stop for a second and imagine yourself in that position. What's the
first thing that comes to mind?
The chances are very good that you had questions:
Does the $50 include tax?
Does the $50 include current shipping charges?
Does the $50 have to be for paper books, or can the order also include
ebooks?
What kind of shipping is offered? Priority? Ground?
What about international orders?
How often will the $50 limit change in the future?
That's what we do. When given something that seems simple, we annoy
people by looking for edge cases and asking about them.
The chances are the client will have already thought of some of these,
and just assumed that the implementation would work that way. Asking the
question just flushes that information out.
But other questions will likely be things that the client hadn't
previously considered. That's where things get interesting, and where a
good developer learns to be diplomatic.
You:
We were wondering about the $50 total. Does that include what we'd
normally charge for shipping?
Client:
Of course. It's the total they'd pay us.
You:
That's nice and simple for our customers to understand: I can see the
attraction. But I can see some less scrupulous customers trying to game
that system.
Client:
How so?
You:
Well, let's say they buy a book for $25, and then select overnight
shipping, the most expensive option. That'll likely be about $30, making
the whole order $55. We'd then make the shipping free, and they'd get
overnight shipping on a $25 book for just $25.
(At this point the experienced developer stops. Deliver facts, and let
the client make the decisions,)
Client:
Ouch. That certainly wasn't what I intended; we'd lose money on those
orders. What are the options?
And this starts an exploration. Your role in this is to interpret what
the client says and to feed back to them the implications. This is both
an intellectual process and a creative one: you're thinking on your feet
and you're contributing to a solution that is likely to be better than
one that either you or the client would have produced alone.
Requirements Are a Process
In the previous example, the developer took the requirements and
fed-back a consequence to the client. This initiated the exploration.
During that exploration, you are likely to come up with more feedback as
the client plays with different solutions. This is the reality of all
requirements gathering:
Tip 77: Requirements Are Learned in a Feedback Loop
Your job is to help the client understand the consequences of their
stated requirements. You do that by generating feedback, and letting
them use that feedback to refine their thinking.
In the previous example, the feedback was easy to express in words.
Sometimes that's not the case. And sometimes you honestly won't know
enough about the domain to be as specific as that.
In those cases, Pragmatic Programmers rely on the “is this what you
meant?” school of feedback. We produce mockups and prototypes, and let
the client play with them. Ideally the things we produce are flexible
enough that we can change them during our discussions with the client,
letting us respond to “that isn't what I meant” with “so more like
this?”
Sometimes these mockups can be thrown together in an hour or so. They
are obviously just hacks to get an idea across.
But the reality is that all of the work we do is actually some form of
mockup. Even at the end of a project we're still interpreting what our
client wants. In fact, by that point we're likely to have more clients:
the QA people, operations, marketing, and maybe even test groups of
customers.
So the Pragmatic Programmer looks at all of the project as a
requirements gathering exercise. That's why we prefer short iterations;
ones that end with direct client feedback. This keeps us on track, and
makes sure that if we do go in the wrong direction, the amount of time
lost is minimized.
Walk in Your Client's Shoes
There's a simple technique for getting inside your clients' heads
that isn't used often enough: become a client. Are you writing a system
for the help desk? Spend a couple of days monitoring the phones with
an experienced support person. Are you automating a manual stock
control system? Work in the warehouse for a week.[70]
As well as giving
you insight into how the system will really be used, you'd
be amazed at how the request “May I sit in for a week while you do
your job?'' helps build trust and establishes a basis for
communication with your clients. Just remember not to get in the way!
Tip 78: Work with a User to Think Like a User
Gathering feedback is also the time to start to
build a rapport with your client base, learning their expectations and
hopes for the system you are building. See
Topic 52, Delight Your Users, for more.
Requirements vs. Policy
Let's imagine that while discussing a Human Resources system, a
client says “Only an employee's supervisors and the personnel
department may view that employee's records.” Is this statement truly
a requirement? Perhaps today, but it embeds business policy in an
absolute statement.
Business policy? Requirement? It's a relatively subtle distinction, but
it's one that will have profound implications for the developers. If the
requirement is stated as “Only supervisors and personnel can view an
employee record,” the developer may end up coding an explicit test
every time the application accesses this data. However, if the
statement is “Only authorized users may access an employee record,”
the developer will probably design and implement some kind of access
control system. When policy changes (and it will), only the metadata for
that system will need to be updated. In fact, gathering requirements in
this way naturally leads you to a system that is well factored to
support metadata.
In fact, there's a general rule here:
Tip 79: Policy Is Metadata
Implement the general case, with the policy information as an example
of the type of thing the system needs to support.
Requirements vs. Reality
In a January 1999 Wired
magazine article,[71] producer and musician
Brian Eno described an incredible piece of technology—the ultimate
mixing board. It does anything to sound that can be done. And yet,
instead of letting musicians make better music, or produce a recording
faster or less expensively, it gets in the way; it disrupts the creative
process.
To see why, you have to look at how recording engineers work. They
balance sounds intuitively. Over the years, they develop an
innate feedback loop between their ears and their
fingertips—sliding faders, rotating knobs, and so on. However, the
interface to the new mixer didn't leverage off those abilities.
Instead, it forced its users to type on a keyboard or click a mouse.
The functions it provided were comprehensive, but they were packaged
in unfamiliar and exotic ways. The functions the engineers needed
were sometimes hidden behind obscure names, or were achieved with
nonintuitive combinations of basic facilities.
This example also illustrates our belief that successful tools
adapt to the hands that use them. Successful requirements gathering
takes this into account. And this is why early feedback, with prototypes
or tracer bullets, will let your clients say “yes, it does what I
want, but not how I want.”
Documenting Requirements
We believe that the best requirements documentation, perhaps the only
requirements documentation, is working code.
But that doesn't mean that you can get away without documenting your
understanding of what the client wants. It just means that those
documents are not a deliverable: they are not something that you give to
a client to sign off on. Instead, they are simply mileposts to help
guide the implementation process.
Requirements Documents Are Not for Clients
In the past, both Andy and Dave have been on projects that produced
incredibly detailed requirements. These substantial documents expanded
on the client's initial two-minute explanation of what was wanted,
producing inch-thick masterpieces full of diagrams and tables. Things
were specified to the point where there was almost no room for ambiguity
in the implementation. Given sufficiently powerful tools, the document
could actually be the final program.
Creating these documents was a mistake for two reasons. First, as we've
discussed, the client doesn't really know what they want up front. So
when we take what they say and expand it into what is almost a legal
document, we are building an incredibly complex castle on quicksand.
You might say “but then we take the document to the client and they sign
off on it. We're getting feedback.” And that leads us to the second
problem with these requirement specifications: the client never reads
them.
The client uses programmers because, while the client is motivated by
solving a high-level and somewhat nebulous problem, programmers are
interested in all the details and nuances. The requirements document is
written for developers, and contains information and subtleties that are
sometimes incomprehensible and frequently boring to the client.
Submit a 200-page requirements document, and the client will likely heft
it to decide if it weighs enough to be important, they may read the
first couple of paragraphs (which is why the first two paragraphs are
always titled Management Summary), and they may flick through the
rest, sometimes stopping when there's a neat diagram.
This isn't putting the client down. But giving them a large technical
document is like giving the average developer a copy of the Iliad in
Homeric Greek and asking them to code the video game from it.
Requirements Documents Are for Planning
So we don't believe in the monolithic, heavy-enough-to-stun-an-ox,
requirements document. We do, however, know that requirements have to be
written down, simply because developers on a team need to know what
they'll be doing.
What form does this take? We favor something that can fit on a real (or
virtual) index card. These short descriptions are often called user
stories. They describe what a small portion of the application should
do from the perspective of a user of that functionality.
When written this way, the requirements can be placed on a board and
moved around to show both status and priority.
You might think that a single index card can't hold the information
needed to implement a component of the application. You'd be right. And
that's part of the point. By keeping this statement of requirements
short, you're encouraging developers to ask clarifying questions. You're
enhancing the feedback process between clients and coders before and
during the creation of each piece of code.
Overspecification
Another big danger in producing a requirements document is being too
specific. Good requirements are abstract. Where
requirements are concerned, the simplest statement that accurately
reflects the business need is best. This doesn't mean you can be
vague—you must capture the underlying semantic invariants as
requirements, and document the specific or current work practices as
policy.
Requirements are not architecture. Requirements are not design, nor
are they the user interface. Requirements are need.
Just One More Wafer-Thin Mint…
Many project failures are blamed on an increase in scope—also known as
feature bloat, creeping featurism, or requirements creep. This is an
aspect of the boiled-frog syndrome from Topic 4, Stone Soup and Boiled Frogs.
What can we do to prevent requirements from creeping up on us?
The answer (again) is feedback. If you're working with the client in iterations with
constant feedback, then the client will experience first-hand the impact
of “just one more feature.” They'll see another story card go up on the
board, and they'll get to help choose another card to move into the next
iteration to make room. Feedback works both ways.
Maintain a Glossary
As soon as you start discussing requirements, users and domain
experts will use certain terms that have specific meaning to them.
They may differentiate between a “client” and a “customer,” for
example. It would then be inappropriate to use either word casually
in the system.
Create and maintain a project glossary—one place that defines
all the specific terms and vocabulary used in a project. All
participants in the project, from end users to support staff, should
use the glossary to ensure consistency. This implies that the glossary
needs to be widely accessible—a good argument for online
documentation.
Tip 80: Use a Project Glossary
It's hard to succeed on a project if users and developers
call the same thing by different names or, even worse, refer to
different things by the same name.
Which of the following are probably genuine requirements? Restate those
that are not to make them more useful (if possible).
The response time must be less than ~500ms.
Modal windows will have a gray background.
The application will be organized as a number of front-end
processes and a back-end server.
If a user enters non-numeric characters in a numeric field, the
system will flash the field background and not accept them.
The code and data for this embedded application must fit within
32Mb.
Challenges
Can you use the software you are writing?
Is it possible to have a good feel for requirements without
being able to use the software yourself?
Pick a non-computer-related problem you currently need to solve.
Generate requirements for a noncomputer solution.
Topic 46. Solving Impossible Puzzles
Gordius, the King of Phrygia, once tied a knot that no one could untie. It was said that whoever solved the riddle of the Gordian Knot would rule all of Asia. So along comes Alexander the Great, who chops the knot to bits with his sword. Just a little different interpretation of the requirements, that's all…. And he did end up ruling most of Asia.
Every now and again, you will find yourself embroiled in the middle of
a project when a really tough puzzle comes up: some piece of
engineering that you just can't get a handle on, or perhaps some bit
of code that is turning out to be much harder to write than you
thought. Maybe it looks impossible. But is it really as hard as it
seems?
Consider real-world puzzles—those devious little bits of wood, wrought
iron, or plastic that seem to turn up as Christmas presents or
at garage sales. All you have to do is remove the ring, or fit the
T-shaped pieces in the box, or whatever.
So you pull on the ring, or try to put the Ts in the box, and quickly
discover that the obvious solutions just don't work. The puzzle can't
be solved that way. But even though it's obvious, that doesn't stop
people from trying the same thing—over and over—thinking there
must be a way.
Of course, there isn't. The solution lies elsewhere. The secret to
solving the puzzle is to identify the real (not imagined) constraints,
and find a solution therein. Some constraints are absolute;
others are merely preconceived notions. Absolute constraints
must be honored, however distasteful or stupid they may appear
to be.
On the other hand, as Alexander proved, some apparent constraints may
not be real constraints at all. Many software problems can be just as
sneaky.
Degrees of Freedom
The popular buzz-phrase “thinking outside the box”
encourages us to recognize constraints that might not be applicable
and to ignore them. But this phrase isn't entirely accurate. If the
“box” is the boundary of constraints and conditions, then the trick
is to find the box, which may be considerably larger than you
think.
The key to solving puzzles is both to recognize the constraints placed on
you and to recognize the degrees of freedom you do
have, for in those you'll find your solution. This is why some puzzles
are so effective; you may dismiss potential solutions too readily.
For example, can you connect all of the dots in the following puzzle
and return to the starting point with just three straight
lines—without lifting your pen from the paper or retracing your
steps (Math Puzzles & Games [Hol92])?
You must challenge any preconceived notions and evaluate whether or
not they are real, hard-and-fast constraints.
It's not whether you think inside the box or outside the box. The
problem lies in finding the box—identifying the real constraints.
Tip 81: Don't Think Outside the Box—Find the Box
When faced with an intractable problem, enumerate all the
possible avenues you have before you. Don't dismiss anything, no
matter how unusable or stupid it sounds. Now go through the list and
explain why a certain path cannot be taken. Are you sure? Can you
prove it?
Consider the Trojan horse—a novel solution to an intractable
problem. How do you get troops into a walled city without being
discovered? You can bet that “through the front door” was initially
dismissed as suicide.
Categorize and prioritize your constraints. When woodworkers begin a
project, they cut the longest pieces first, then cut the smaller
pieces out of the remaining wood. In the same manner, we want to
identify the most restrictive constraints first, and fit the remaining
constraints within them.
Sometimes you will find yourself working on a problem that seems much
harder than you thought it should be. Maybe it feels like you're
going down the wrong path—that there must be an easier way than this!
Perhaps you are running late on the schedule now, or even despair of
ever getting the system to work because this particular problem is
“impossible.”
This is an ideal time to do something else for a while. Work on
something different. Go walk the dog. Sleep on it.
Your conscious brain is aware of the problem, but your conscious brain
is really pretty dumb (no offense). So it's time to give your real
brain, that amazing associative neural net that lurks below your
consciousness, some space. You'll be amazed how often the answer will
just pop into your head when you deliberately distract yourself.
If that sounds too mystical for you, it isn't. Psychology
Today[72]
reports:
To put it plainly—people who were distracted did better on a complex
problem-solving task than people who put in conscious effort.
If you're still not willing to drop the problem for a while, the next
best thing is probably finding someone to explain it to. Often, the
distraction of simply talking about it will lead you to enlightenment.
Have them ask you questions such as:
Why are you solving this problem?
What's the benefit of solving it?
Are the problems you're having related to edge cases? Can you
eliminate them?
Is there a simpler, related problem you can solve?
This is another example of Rubber Ducking in practice.
Fortune Favors the Prepared Mind
Louis Pasteur is reported to have said:
Dans les champs de l'observation le hasard ne favorise que les esprits
préparés. (When it comes to observation, fortune favors the prepared mind.)
That is true for problem solving, too. In order to have those eureka!
moments, your nonconscious brain needs to have plenty of raw material;
prior experiences that can contribute to an answer.
A great way to feed your brain is to give it feedback on what works and
what doesn't work as you do your daily job. And we describe a great way
to do that using an Engineering Daybook (Topic 22, Engineering Daybooks).
And always remember the advice on the cover of The Hitchhiker's Guide to
the Galaxy: DON'T PANIC.
Take a hard look at whatever difficult problem you are embroiled
in today. Can you cut the Gordian knot? Do you have to do it this
way? Do you have to do it at all?
Were you handed a set of constraints when you signed on to your
current project? Are they all still applicable, and is the
interpretation of them still valid?
Topic 47. Working Together
I've never met a human being who would want to read 17,000 pages of documentation, and if there was, I'd kill him to get him out of the gene pool.
Joseph Costello, President of Cadence
It was one of those “impossible” projects, the kind you hear about that sounds both exhilarating and terrifying at the same time. An ancient system was approaching end-of-life, the hardware was physically going away, and a brand-new system had to be crafted that would match the (often undocumented) behavior exactly. Many hundreds of millions of dollars of other people's money would pass through this system, and the deadline from inception to deployment was on the order of months.
And that is where Andy and Dave first met. An impossible project with a ridiculous deadline. There was only one thing that made the project a roaring success. The expert who had managed this system for years was sitting right there in her office, just across the hall from our broom closet–sized development room. Continuously available for questions, clarifications, decisions, and demos.
Throughout this book we recommend working closely with users; they are part of your team. On that first project together, we practiced what now might be called pair programming or mob programming: one person typing code while one or more other team members comment, ponder, and solve problems together. It's a powerful way of working together that transcends endless meetings, memos, and overstuffed legalistic documentation prized for weight over usefulness.
And that's what we really mean by “working with”: not just asking questions, having discussions, and taking notes, but asking questions and having discussions while you're actually coding.
Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.
That is, the social structures and communication pathways of the team and the organization will be mirrored in the application, website, or product being developed. Various studies have shown strong support for this idea. We've witnessed it first-hand countless times—for example, in teams where no one talks to each other at all, resulting in siloed, "stove-pipe" systems. Or teams that were split into two, resulting in a client/server or frontend/backend division.
Studies also offer support for the reverse principle: you can deliberately structure your team the way you want your code to look. For example, geographically distributed teams are shown to tend toward more modular, distributed software.
But most importantly, development teams that include users will produce software that clearly reflects that involvement, and teams that don't bother will reflect that, too.
Pair Programming
Pair programming is one of the practices of eXtreme Programming that has become popular outside of XP itself. In pair programming, one developer operates the keyboard, and the other does not. Both work on the problem together, and can switch typing duties as needed.
There are many benefits to pair programming. Different people bring different backgrounds and experience, different problem-solving techniques and approaches, and differing levels of focus and attention to any given problem. The developer acting as typist must focus on the low-level details of syntax and coding style, while the other developer is free to consider higher-level issues and scope. While that might sound like a small distinction, remember that we humans have only so much brain bandwidth. Fiddling around with typing esoteric words and symbols that the compiler will grudgingly accept takes a fair bit of our own processing power. Having a second developer's full brain available during the task brings a lot more mental power to bear.
The inherent peer-pressure of a second person helps against moments of weakness and bad habits of naming variables foo and such. You're less inclined to take a potentially embarrassing shortcut when someone is actively watching, which also results in higher-quality software.
Mob Programming
And if two heads are better than one, what about having a dozen diverse people all working on the same problem at the same time, with one typist?
Mob programming, despite the name, does not involve torches or pitchforks. It's an extension of pair programming that involves more than just two developers. Proponents report great results using mobs to solve hard problems. Mobs can easily include people not usually considered part of the development team, including users, project sponsors, and testers. In fact, in our first “impossible” project together, it was a common sight for one of us to be typing while the other discussed the issue with our business expert. It was a small mob of three.
You might think of mob programming as tight collaboration with live coding.
What Should I Do?
If you're currently only programming solo, maybe try pair programming. Give it a minimum of two weeks, only a few hours at a time, as it will feel strange at first. To brainstorm new ideas or diagnose thorny issues, perhaps try a mob programming session.
If you are already pairing or mobbing, who's included? Is it just developers, or do you allow members of your extended team to participate: users, testers, sponsors…?
And as with all collaboration, you need to manage the human aspects of it as well as the technical. Here are just a few tips to get started:
Build the code, not your ego. It's not about who's brightest; we all have our moments, good and bad.
Start small. Mob with only 4-5 people, or start with just a few pairs, in short sessions.
Criticize the code, not the person. “Let's look at this block” sounds much better than “you're wrong.”
Listen and try to understand others' viewpoints. Different isn't wrong.
Conduct frequent retrospectives to try and improve for next time.
Coding in the same office or remote, alone, in pairs, or in mobs, are all effective ways of working together to solve problems. If you and your team have only ever done it one way, you might want to experiment with a different style. But don't just jump in with a naive approach: there are rules, suggestions, and guidelines for each of these development styles. For instance, with mob programming you swap out the typist every 5-10 minutes.
Do some reading and research, from both textbook and experience reports, and get a feel for the advantages and pitfalls you may encounter. You might want to start by coding a simple exercise, and not just jump straight into your toughest production code.
But however you go about it, let us suggest one final piece of advice:
Tip 82: Don't Go into the Code Alone
Topic 48. The Essence of Agility
You keep using that word, I do not think it means what you think it means.
Inigo Montoya, The Princess Bride
Agile is an adjective: it's how you do something. You can be an agile
developer. You can be on a team that adopts agile practices, a team that
responds to change and setbacks with agility. Agility is your style, not
you.
Tip 83: Agile Is Not a Noun; Agile Is How You Do Things
As we write this, almost 20 years after the inception of the Manifesto
for Agile Software Development,[73] we see many, many developers
successfully applying its values. We see many fantastic teams who find
ways to take these values and use them to guide what they do, and how
they change what they do.
But we also see another side of agility. We see teams and companies
eager for off-the-shelf solutions: Agile-in-a-Box. And we see many
consultants and companies all too happy to sell them what they want. We
see companies adopting more layers of management, more formal reporting,
more specialized developers, and more fancy job titles which just mean
“someone with a clipboard and a stopwatch.”[74]
We feel that many people have lost sight of the true meaning of agility,
and we'd like to see folks return to the basics.
Remember the values from the manifesto:
We are uncovering better ways of developing
software by doing it and helping others do it.
Through this work we have come to value:
Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan
That is, while there is value in the items on
the right, we value the items on the left more.
Anyone selling you something that increases the importance on things on
the right over things on the left clearly doesn't value the same things
that we and the other manifesto writers did.
And anyone selling you a solution-in-a-box hasn't read the introductory
statement. The values are motivated and informed by the continuous act
of uncovering better ways to produce software. This is not a static
document. It's suggestions for a generative process.
There Can Never Be an Agile Process
In fact, whenever someone says “do this, and you'll be agile,” they are
wrong. By definition.
Because agility, both in the physical world and in software development,
is all about responding to change, responding to the unknowns you
encounter after you set out. A running gazelle doesn't go in a straight
line. A gymnast makes hundreds of corrections a second as they respond
to changes in their environment and minor errors in their foot
placement.
So it is with teams and individual developers. There is no single plan
you can follow when you develop software. Three of the four values tell
you that. They're all about gathering and responding to feedback.
The values don't tell you what to do. They tell you what to look for
when you decide for yourself what to do.
These decisions are always contextual: they depend on who you are, the
nature of your team, your application, your tooling, your company, your
customer, the outside world; an incredibly large number of factors, some
major and some trivial. No fixed, static plan can survive this
uncertainty.
So What Do We Do?
No one can tell you what to do. But we think we can tell you something
about the spirit with which you do it. It all boils down to how you deal
with uncertainty. The manifesto suggests that you do this by gathering
and acting on feedback. So here's our recipe for working in an agile
way:
1. Work out where you are.
2. Make the smallest meaningful step towards where you want to be.
3. Evaluate where you end up, and fix anything you broke.
Repeat these steps until you're done. And use them recursively, at every
level of everything you do.
Sometimes even the most trivial-seeming decision becomes important when
you gather feedback.
“Now my code needs to get the account owner.
let user = accountOwner(accountID);
Hmmm… user is a useless name. I'll make it owner.
let owner = accountOwner(accountID);
But now that feels a little redundant. What am I actually trying to do
here? The story says that I'm sending this person an email, so I need to
find their email address. Maybe I don't need the whole account owner at
all.
let email = emailOfAccountOwner(accountID);
By applying the feedback loop at a really low level (the naming of a
variable) we've actually improved the design of the overall system,
reducing the coupling between this code and the code that deals with accounts.
The feedback loop also applies at the highest level of a project. Some
of our most successful work has happened when we started working on a
client's requirements, took a single step, and realized that what we
were about to do wasn't necessary, that the best solution didn't even
involve software.
This loop applies outside the scope of a single project. Teams should
apply it to review their process and how well it worked. A team that
doesn't continuously experiment with their process is not an agile
team.
And This Drives Design
In Topic 8, The Essence of Good Design we assert that the measure of design is
how easy the result of that design is to change: a good design produces something
that's easier to change than a bad design.
And this discussion about agility explains why that's the case.
You make a change, and discover you don't like it. Step 3 in our list
says we have to be able to fix what we break. To make our feedback loop
efficient, this fix has to be as painless as possible. If it isn't,
we'll be tempted to shrug it off and leave it unfixed. We talk about
this effect in Topic 3, Software Entropy. To make this whole
agile thing work, we need to practice good design, because good design
makes things easy to change. And if it's easy to change, we can adjust,
at every level, without any hesitation.
The simple feedback loop isn't just for software. Think of other
decisions you've made recently. Could any of them have been improved by
thinking about how you might be able to undo them if things didn't take
you in the direction you were going? Can you think of ways you can
improve what you do by gathering and acting on feedback?
[70]Does a week
sound like a long time? It really isn't, particularly when you're
looking at processes in which management and workers occupy
different worlds. Management will give you one view of how
things operate, but
when you get down on the floor, you'll find a very different
reality—one that will take time to assimilate.