This “Architecture in an Agile World” project started in fall 2009,
with a discussion-based workshop at the ACM OOPSLA 2009 conference.
This workshop explored some of the basic ideas of how best
to use architectural thinking and software models in the context
of agile development.
There is a fair amount of disagreement about the nature of the
relationship between agility and architecture.
Philippe Kruchten and George Fairbanks have probably the most
moderate points of view on this topic.
Architecture in an Agile World - workshop at the SPLASH 2010 conference:
Useful articles on Agile and Architecture
The following articles provide useful background to understand
the costs and benefits of doing some architecture work in agile projects.
Useful architecture techniques for agile projects
The following articles explain several useful techniques to use
in order to build lightweight and flexible architectures:
Useful quotes
A good quote from Kent Beck:
“Since most of the cost of a program will be incurred after it is
first deployed, programs should be easy to change. The flexibility
I imagine will be needed tomorrow, though, is likely to be not what
I need when I change the code. That’s why the flexibility of
simplicity and extensive tests is more effective than
the flexibility offered by speculative design.”
(Kent Beck, Implementation Patterns, p. 12)
A good quote from Eric Evans:
“Design free-for-alls produce systems no one can make sense of as a
whole, and they are very difficult to maintain. But architectures can
straitjacket a project with up-front design assumptions and take too
much power away from the developers/designers of particular parts of
the application. Soon, developers will dumb down the application to fit
the structure, or they will subvert it and have no structure at all,
bringing back the problems of uncoordinated development.”
“Therefore: Let this conceptual large-scale structure evolve with the
application, possibly changing to a completely different type of
structure along the way. Don’t overconstrain the detailed design and
model decisions that must be made with detailed knowledge.”
(Eric Evans, Domain-Driven Design, chapter 16)
A good quote from Luke Hohmann:
“The role of architecture in agile software
development is pretty interesting. Some practitioners
equate architectural planning to “Big Up Front Design”
(BUFD) and minimize its importance. We believe that
this is inappropriate, and instead believe that up-front
architectural analysis and design is critically important
to the long-term success of agile projects.
That said, every architecture, no matter how well-designed,
must be maintained. This can be a challenge
in agile teams who focus their attention on backlog
items that are most associated with top-line revenue
growth and/or customer demands. To combat this
tendency, we advocate anthropomorphizing the system.
This enables the system to literally “have a voice” in
its own “care and feeding” and helps encourage agile
teams to make architectural investments that are every
bit as important to the long-term needs of the business
as various features are to other customers.”
(Peter Hodgkins and Luke Hohmann, “Agile Program Management: Lessons
Learned from the VeriSign Managed Security Services Team,”
Agile 2007, DOI: 10.1109/AGILE.2007.11)
Architecture smells
Is my agile project doing an adequate amount of architecture work?
One way to tell is to look for “architecture smells” – indications
that you are doing extra work that could be avoided with more
attention to architecture.
If your code has some of these “smells,” the code
may be trying to tell you something – your developers have
been somewhat undisciplined in their design and coding work,
and therefore you haven’t
been spending enough time on addressing architectural issues.
The following partial list of architecture smells was proposed in
the SPLASH 2010 workshop:
- Code that nobody wants to change
- (they are afraid to change it because
it is complex or cryptic, and they don't want to break anything)
- Missing metaphor
- (the team and customers need a common shared
understanding and vocabulary about the problem)
- Overreliance on “refactoring iterations” to fix technical debt
- (It is generally OK to have some refactoring iterations that are
driven by architecture changes and evolution.)
- Abstractions that are hard to understand or communicate
- Missing -ility stories / tests / strategies
- (A related issue: If you have many successive failures of -ility tests
in a series of iterations, it might be a sign of a lack of progress
on making improvements to the architecture.)
- Untestable code
- (In the book Working Effectively With Legacy Code, Michael Feathers
defines the term “legacy code” to mean “code without
any tests.” If you have a lot of code that is difficult to test,
that code will be never really improve until you start building
tests that make it possible to understand the code’s actual behavior.)
- Unbalanced test suite
- (too many unit tests, not enough functional tests)
- Test churn
- (Small design changes trigger a number of changes in the
automated tests – could be caused by poor technique in the implementation
of tests, but there might be some architecture issues as well.)
- Problems in design evolution – the problem is sometimes called
“you can’t get there from here.” You have a design that is too
rigid.
- Inconsistent use of infrastructure
- (For example, there are some modules that use a standard messaging
component while other components use some special local messaging code.
It isn’t really “wrong,” but it increases the learning curve for new
project members, and it might cause long-term maintenance issues.)
- General violations of architecture standards
- Missing boundary stories
- (How does your system interact with other systems?
What end-to-end stories do you need to write to understand the
interface requirements between your system and external systems?)
- Duplication without reason
- (Examples: using two different databases, multiple interface
mechanisms.)
- A number of incidents in operations
- (If the system is hard to use, easy to make configuration mistakes,
or it is easy to get things into an error state – this might
indicate that you missed some requirements or you might have
some other architecture gaps to address.)
Last modified: Oct. 25, 2018