#
"Plans are worthless, but planning is everything." #
# -- Dwight D. Eisenhower.
Here are some suggestions for groups that may have recently
adopted Agile methods. I am a long-time fan, but I have also
seen Agile processes used to support SOLID waterfall habits.
* What are Agile iterations for? *
Someone who learns about Agile development entirely from new
management practices may mistake the purpose of iterations.
These are not simply milestones in a pre-determined schedule.
All Agile practices begin with "early and continuous delivery."
At the end of an iteration, an updated functioning product can
be tested and shared. Everything visible in the product does
something useful. All features are reconciled with each other.
For each iteration you decide what will be the most useful
additional functionality, given what you already have. Because
you track your development velocity, you know how much progress
is feasible. Because you always build on a stable product, you
work at full efficiency.
Users help you refine the product throughout the development
process, not just during a final beta testing period. When
your schedule ends, then you ship the most useful product
possible in the available time. You avoid an unpredictable
stabilization period.
http://agilemanifesto.org/principles.html
http://en.wikipedia.org/wiki/Agile_software_development
* Iterative waterfall *
The biggest pitfall of all, perhaps, is not actually iterating
the priorities: [[Prioritizing_features.html]]. Do not attempt
to plan every iteration for the entire project in advance.
Otherwise, you might as well still be working with Gantt
charts. You will lose flexibility and pass up unexpected
opportunities.
It is misleading in Agile development to ask if you are ahead
or behind schedule. You are trying to complete the most useful
features of your system first. You have not finished a feature
if it depends on functionality scheduled later. If you add
features to an unstable system, then you are already behind
schedule, because you have no idea how long stabilization will
take.
* Tracking velocity *
Do not devote too much time to estimating project velocity --
what did you do, how long did you think it would take, and how
long did it actually take. It is important to estimate
velocity so that your product owners have reasonable
expectations about what can be delivered at some future dates.
You may also have other independent teams as internal customers
of your work, who must adjust their plans accordingly. Within
the group, you expect velocities to help you choose the right
number of stories for each single iteration. If these are the
problems to be solved, then collect just enough data to solve
them. Do not collect data just because the process asks for
it. Meetings should concentrate on clarifying functionality
and customer priorities, not on tracking velocities.
You do want to know how fast you are making progress, so that
no one promises too much, or too little. You may think your
sales channel needs to know exactly what you are planning to
build before you build it. I bet they would rather know
exactly what they can count on (because it already works), what
you plan to do next (likely to get done), and how fast you are
moving. Maybe they would prefer an early version of the
product that a customer can safely try out, however incomplete.
They do not want a precise description of a product that then
slips unpredictably for cleanup and feature triage.
* Shorter iterations *
Iterations may be too long. Agile and lightweight methods work
best with short iterations. I prefer one week, but two weeks
is probably the most common. Three weeks is stretching it, and
four or five weeks is no longer an iteration, but a
mini-project.
When iterations are short, there is less need to estimate
velocity perfectly. If some tasks were too big for the
previous iteration, then you will try smaller ones for the
next.
* Distributing chores *
Too many developers may be developing subsystems independently.
I think it essential for at least two developers to understand
and feel comfortable with everything checked into the system.
Instead of deciding on one developer for each task, always find
two. That might mean fewer tasks get assigned each iteration,
but you are likely to see more tasks actually get done, with
less rework later.
When developers share the design and implementation, no one is
critical path any longer. It is much easier to redistribute
work as necessary. If someone runs out of tasks, or needs
help, it is a great chance to share some expertise.
If you use a tracking system, then make sure you can assign a
task to two owners at once, to encourage pair programming.
* Do not misuse metrics *
Management should not use Agile software to monitor programmer
productivity. Some programmers may then compete to show
progress on a larger number of stories, breaking into
unnecessarily small tasks. This does not help the planning of
the project. Worse, this accidental metric could work against
collaboration. If you want to know how someone contributes to
a project, ask them and their coworkers. It is hard to hide in
a genuinely Agile project.
* Staying Agile *
With shorter iterations, tasks become more granular and easier
to tell when they are complete. You do not need a long meeting
to plan them out. You will actually measure velocity more
frequently, with less effort, and get better at it.
Long or predetermined iterations (mini-projects) add inertia.
It is harder for architects to adjust the overall design of the
product. You may have a remarkably well-defined workflow, but
be careful that it has not gelled too fast. Habitual processes
may force you to identify big chucks of functionality for many
iterations at a time. You then commit to substantial designs
before your representative users have a chance to respond.
Flexibility is lost.
Instead of using big iteration meetings to solve design issues,
you can identify the right people to handle those designs in
the next short iteration.
* Doneness *
Iterations should concentrate on user stories, not
implementation details or development tasks. Stories
invariably evolve during an iteration. Is the user able to
solve the problem he wanted, though maybe not as anticipated?
You want to take advantage of clever implementations that could
not be anticipated when the story was originally conceived.
Sometimes an eighty-percent solution is simpler and more
elegant, with more complicated use-cases delayed to a later
iteration. Sometimes you can add more functionality than you
remove. Everyone should encourage this sort of flexibility.
Stories should be revised, split, and morphed as necessary.
On the other hand, an implementation should never pretend to do
more than it actually does. A broken solution is not
acceptable on any level. If the application blows up for
certain cases, then disallow and hide those options. Make sure
that you do not allow broken features to improve an arbitrary
velocity metric.
* Technical practices *
Many popularizations of Agile methods avoid any prescription of
technical practices. Scrum, for example, concentrates on
project management and scheduling.
Here are some warnings about this emphasis from Agile leaders:
http://www.infoq.com/news/2009/02/whole-enchilada-and-context ,
http://jamesshore.com/Blog/The-Decline-and-Fall-of-Agile.html
Metrics for progress and "burn rates" cannot neglect stability
and efficiency for everyone.
For example, I still never see enough unit tests in code. I
would use a code coverage tool like "cobertura" to see how much
of code is actually being tested automatically. Without proper
test coverage, continuous integration becomes impossible.
Tests define what the code does and how to use it. Tests allow
developers to share work on code: [[Unit_Tests.html]]
A project reaches full velocity when the environment supports
continuous integration. New features can be completely
reconciled with a fully functioning system. Programmers can
safely update their code from the repository at any time.
Tests allow programmers to refactor and clean up the code
without fear of breaking anything. Dead code disappears.
Every line and feature is useful.
* Refactor your processes *
Remember that every management process carries a cost, in time
and effort. If you add a process to solve a new problem, then
also try to remove a process for a problem that no longer
exists. In programming this is called refactoring.
Bill Harlan, 2008-2009