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

  1. 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
    ).
  2. 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.
  3. 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.
  4. 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
    .
  5. 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.
  6. 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.
  7. 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.
  8. Prove it with code. Never assume your
    design works; instead, obtain

    concrete feedback by writing code
    to determine
    if it does in fact work.
  9. 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.
  10. 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
    .
  11. 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

    t
    esting, 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
    .
  12. 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.
  13. 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.
  14. 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
    .
  15. 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
    .
  16. 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.
  17. 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).


Agile Lifecycle

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.

Source Article