This article overviews design
strategies for agile software development teams.
These strategies are critical for scaling agile
software development to meet the real-world
needs of modern IT organizations. The
Agile approach to design is very different than
the traditional approach, and apparently
more effective too. It is important to
understand:
1.
Agile
Design
Practices
There
is a
range of
agile
design
practices,
see
Figure 1,
from
high-level
architectural
practices
to
low-level
programming
practices.
Each of
these
practices
are
important,
and each
are
needed
if your
team is
to be
effective
at agile
design.
Figure 1.
Agile
design
practices.
2.
Agile
Design
Philosophies
- Agile designs are emergent, they’re not
defined up front. Your overall system design
will emerge over time, evolving to fulfill new
requirements and take advantage of new technologies
as appropriate. Although you will often do some
initial architectural modeling at the very
beginning of a project during “iteration 0” this will be
just enough to get your team going. Agilists don’t
need to get a fully documented set of models in
place before you may begin coding (although
sometimes, just sometimes, you may need to
perform
look-ahead modeling). - Your unit tests form much of your detailed
design documentation. With a
test-driven development (TDD) approach to
development you write a test and then you write just
enough domain code to fulfill that test. An
important side effect of this approach is that your
unit tests not only validate your code, they also
form the majority of your design documentation in
the form of
executable specifications.
TDD is complementary to
AMDD and is actually scaled by AMDD. - Design models need to be
just barely good
enough. You don’t need to model every single
detail in your models, the models don’t need to be
perfect, and they certainly don’t need to be
complete. Remember the last time you coded from a
design spec (if you ever did)? Did you really look
at all the fine-grained details? No, because you
were competent enough to handle the details
yourself. - Multiple models. Effective developers
realize that each type of model has its strengths
and weaknesses, therefore they need to apply the
right model(s) for the job at hand. Because
software development is complex you quickly realize
that you need to know about a wide range of models
in order to be effective. All of the models
mentioned in this newsletter, and more, are
described at the
Agile Models Distilled page. - You typically only need a subset of the
models. Although there are many modeling
techniques available to your, the fact is that any
given project team will only require a subset.
Think of it like this: in your toolbox at home you
have a wide array of screwdrivers, wrenches, pliers,
and so on. For any given repair job you will use
only a few of the tools. Different jobs, different
tools. You never need all of your tools at once,
but over time you will use them in a variety of
manners. - Each model can be used for a variety of
purposes. A
UML class diagram can be used to depict a
high-level domain model or a low-level design,
not to mention things in between. Use cases can be
used to model the essential nature of a process or
the detailed system usage description which takes
into account architectural decisions. Never
underestimate how flexible you can be with models. - Designers should also code. Whenever a
model is handed over to someone else to code there
is significant danger that the programmer will not
understand the model, will miss some of its nuances,
or may even ignore the model completely in favor of
their own approach. Furthermore, even when
hand-offs are successful you will discover that you
need far more details in your models than if you had
simply coded it yourself. In short, separating
design from programming is a risky and expensive
proposition. It is far more effective to have
generalizing specialists on your team that can both
design and code. - Prove it with code. Never assume your
design works; instead, obtain
concrete feedback by writing code to determine
if it does in fact work. - Feedback is your friend. Never forget
that you are a mere mortal just like everyone else
on your team. Expect to receive feedback — I
suggest you actively seek it — about your work and
be prepared to consider it and act accordingly. Not
only will your system be the better for it, you will
likely learn something in the process. -
Sometimes the simplest tool
is a complex CASE tool. When it comes to
requirements I prefer
inclusive tools such as paper and whiteboards,
but when it comes to design I tend to lean towards
sophisticated tools which (re)generate code for me.
Like my grandfather always said, you should use the
right tool for the job. - Iterate, iterate, iterate. With an
iterative approach to development you work a bit on
requirements, do a bit of analysis, do a bit of
design, some coding, some
testing, and iterate
between these activities as needed. You will also
iterate back and forth between working on various
artifacts, working on the
right artifact at the right time. - Design is so important you should do it every
day. It is critical to think through how you’re
going to build something, to actually design it,
before you build it. Your design efforts may take
on the form of a sketch on a whiteboard, a detailed
model created with a sophisticated modeling tool, or
a simple test that you write before you write
business code. Agile developers realize that design
is so important that they do it every day, that
design isn’t just a phase that you do early in the
project before getting to the “real work” of writing
the source code. - Design for your implementation environment
judiciously. Take advantage of features of your
implementation environment, but be smart about it.
Trade-offs are normal, but understand the
implications and manage the risks involved. Every
time you take advantage of a unique performance
enhancement in a product (such as a database,
operating system, or middleware tool) you are likely
coupling your system to that product and, thus,
reducing its portability. To minimize the impact of
your implementation environment on your systems, you
can layer your software and wrap specific features
to make them appear general to their users. - Document complicated things. If it is
complicated, then document it thoroughly. Better
yet, invest the time to design it so it is simple.
Remember the AM practice
Create Simple Content. - Do not over document. You need to
document your design, but you shouldn’t over
document either. Remember, users pay you to build
systems, not to document them. There is a fine line
between under documenting and over documenting, and
only through experience are you able to find it.
Be as
agile as possible when it comes to documentation. - Don’t get sidetracked by the data community.
Unfortunately many within the data community believe
that you require a serial approach to design,
particularly when it comes to databases. This
belief is the result of either not understanding
evolutionary development or some misguided need
to identify the
“one
truth above all else”. Evolutionary
database design techniques such as
agile data modeling,
database refactoring, and
database regression testing work incredibly well
in practice. - Remember user experience (UX). To your end user,
the user interface (UI) is the system. The implication is that an important
aspect of your design is the UX. For more information, see
Introduction to Agile Usability and
How to Integrate Design Into Your Agile Process.
3. Design Throughout The
Lifecycle
Figure 2
depicts
the
generic
agile
software
development
lifecycle.
For the
sake of
discussion,
the
important
thing to
note is
that
there is
no
design
phase,
nor a
requirements
phase
for that
matter,
which
traditionalists
are
familiar
with.
Agile
developers
will do
some
high-level
architectural
modeling
during
Iteration
0, also
known as
the
warm-up
phase,
and
detailed
design
during
development
iterations
and even
during
the end
game (if
needed).
Figure 2. The Agile SDLC (click to expand).
Figure
3 depicts the
Agile
Model
Driven
Development
(AMDD)
lifecycle,
the
focus of
which is
how
modeling
fits
into the
overall
agile
software
development
lifecycle.
Early in
the
project
you need
to have
at least
a
general
idea of
how
you’re
going to
build
the
system.
Is it a
mainframe
COBOL
application?
A .Net
application?
J2EE?
Something
else?
During
Iteration
0 the developers on the project will get together in a room,
often around a whiteboard, discuss and then sketch out a potential
architecture for the system. This architecture will likely evolve over
time, it will not be very detailed yet (it just needs to be
good
enough for now), and very little documentation (if any) needs to be
written.
The goal
is to
identify
an
architectural
strategy,
not
write
mounds
of
documentation.
Figure 3. The AMDD
lifecycle.
When a developer has a new requirement to implement
they ask themselves if
they understand what is being asked for. If not,
then
they do
some
just-in-time
(JIT)
“model
storming”
to
identify
a
strategy
for
implementing
the
requirement.
This
model
storming
is
typically
done at
the
beginning
of an
iteration
during
the
detailed
planning
effort
for that
iteration,
or
sometime
during
the
iteration
if they
realize
that
they
need to
explore
the
requirement
further.
Part of
this
modeling
effort
will be
analysis
of the
requirement
as well
as
design
of the
solution,
something
that
will
typically
occur on
the
order of
minutes.
In
Extreme
Programming
(XP)
they
refer to
this as
a “quick
design
session”.
If the
team is
taking a
Test-Driven
Development
(TDD)
approach
the
detailed
design
is
effectively
specified
as
developer
tests,
not as
detailed
models.
Because
you
write a
test
before
you
write
enough
production
code to
fulfill
that
test you
in
effect
think
through
the
design
of that
production
code as
you
write
the
test.
Instead
of
creating
static
design
documentation,
which is
bound to
become
out of
date,
you
instead
write an
executable
specification
which
developers
are
motivated
to keep
up to
date
because
it
actually
provides
value to
them.
This
strategy
is an
example
of the
AM
practice
of
single
sourcing
information,
where
information
is
captured
once and
used for
multiple
purposes.
In this
case for
both
detailed
specification
and for
confirmatory
testing.
When you
stop and
think
about
it,
particularly
in
respect
to
Figure 2,
TDD is a
bit of a
misnomer.
Although
your
developer
tests
are
“driving”
the
design
of your
code,
your
agile
models
are
driving
your
overall
thinking.
More Stories
What to Do If Your Oil Tank Is Leaking
Parnassus Research and Academic Building Design and Site Improvements Move Forward
Consider 3 popular design trends when designing your dream home