Last
year, I resolved that in 2007 I'd focus on the essential characteristics of
technology that help maximize the effectiveness of agile practices. Since about
90 percent of folks don't keep their resolutions throughout the year, I've
decided this year not to make any such promises. Instead, I'll let you make
your own resolutions this year, and will offer up a few tips that you might
want to consider seriously if you're interested in increasing your personal or
team's agility.
Team Agility
Increasing
team agility is incredibly difficult as it requires a shift in thinking by all
members of the team. There is no magic bullet. For those teammates who might be
most comfortable with a waterfall lifecycle, transitioning to an agile approach
is fraught with doubt. But adopting a few simple practices, while steering
clear of others, can help increase your team's agility without ever mentioning
the "a" word.
Ignore
Traceability.
Many teams are quite enamored with traceability. Changes to requirements can be
traced through the analysis and design model into the code through the
components and onto the executable nodes. But traceability is fundamentally
flawed due to synchronization issues across artifacts. Teams do not possess the
discipline necessary to maintain consistency across all artifacts, making the
source code the only true artifact representing the current state of the
system. If you're not on a team that values traceability, then you're off to a
great start in 2008. But if you are, admit that traceability is a myth and turn
your attention toward the source.
Advertisement
Test
Early. I've
worked on, observed, and spoken to numerous teams interested in increasing
their agility. Some had a robust continuous integration strategy in place. Some
strove to achieve 100 percent test coverage. Some refactored mercilessly to
ensure a resilient and extensible design. And some developed using timeboxed
iterations, engaged the customer throughout the lifecycle, and planned
continuously. Yet, not all of these teams felt agile. I've also worked on teams that have felt far from agile, in that
their practices weren't consistent with the vision of the agile manifesto, nor
were they considered "best," but these teams always seemed to create software
that did what their business partners needed. What was the differentiating
factor? Teams that create great software test early and test continuously. To
test, you must have two critical components in place - a tester and an
application to test. The earlier you test your software, the sooner you prove
you have software that works. As testing requires a tester, Quality Assurance
gets involved very early in the project lifecycle, and the big bang approach to
integration and series of handoffs that often take place on traditional
projects are avoided.
Allow Emergent
Roles. Teams
often assign individuals to specific roles. In some situations, this makes
sense. Not all developers make a good project manager, and if you know you need
a good project manager, then you need to find someone capable of managing your
project, whether that individual be found through a new hire, contractor, or
from within your team. But in other cases, individuals are prematurely assigned
to specific roles. Anointing someone software architect is but one example.
While other members of the team might be more qualified, they are not allowed
to fill the role due to organizational issues, workload, or resource
constraints. Assigning roles where each role has specialized responsibilities
doesn't leverage the individual strengths of team members. In The
Agile Matrix, I spoke of various ways to organize team structure, and allow
roles to emerge naturally from within the software development team results in
greater team cohesion. Instead of starting big with individuals allocated to
certain roles, start small where each member of the team is a developer. Team
members will naturally gravitate toward their individual specialty based on
their strengths and interest. Then, as gaps are identified, search for
additional developers to fill those gaps.
Build
Often. The only
true barometer of project progress is a functional software application. If you
don't have a functional software product, you cannot accurately assess the
current state of the project. A robust continuous integration strategy is the
cornerstone of any team getting started with agility. To test you need a
software system to test, and if you can't build it, you can't test it.
Avoid
Contracts. A typical software lifecycle
begins with IT developing estimates that help gauge how long it will take to
deliver the software system. Once they've provided acceptable estimates, business
and IT draw up a contract and include other
important agreements, such as Service Level Agreements (SLA). Once the contract
is signed, work commences. Contracts ensure that IT and business will always be
on different sides. If you want to create greater team cohesion between IT and
your business partners, avoid contracts like the plague. Instead, use
functional software, frequent demos, and constant customer collaboration to
guide the development effort.
Developer Agility
Increasing
your personal agility impacts how you, as an individual developer, go about
doing your work every day. If you're interested in increasing the quality of
code you create, or delivering more valuable features to your users, a good
place to start is by practicing some of the items below.
Run the
Tests. If you're
not already writing unit tests, you need to start, and that should become your
first professional resolution of the year. If you are writing tests, be sure
you run them multiple times per day. Ideally, each time you make a change to
the code.
Avoid
BDUF. If you
practice test driven development, chances are you're already an advocate of
emergent design. Perhaps, however, you've believed that unit testing is really
only about testing. If you're still spending considerable time crafting UML
diagrams or other design documents, try foregoing their creation just once and
allow the design to emerge. Instead, spend a bit of time sketching on a piece
of paper your high-level design, and let the tests drive the design by placing
emphasis on testing classes in isolation. It's a natural way to ensure classes
are decoupled and methods are cohesive, and with a robust suite of tests in
place, you'll be much more effective at the refactoring you'll need to do
regardless of the approach you take toward design.
Write
Quality Code. It should be every developer's
professional code of conduct to write the highest quality code he or she is
capable of writing, but writing high quality code is difficult. And in many
situations, I doubt that we ever set out to create intentionally crappy code.
Instead, it just winds up that way. Aim high to create code that is expressive,
well-tested, and highly cohesive. Ensure designs are resilient and extensible.
Use tools that can help you.
Avoid
Big Tools. For some odd reason, we're led to
believe that the larger the software system, the larger the tools we need. We
treat large software development efforts like we do large construction
projects. The larger the project, the bigger the equipment and tools needed.
Yet big tools are often cumbersome and difficult to use, and often involve an
extensive learning curve. In last
years resolution, I laid out some guidelines for choosing tools that
support an agile developers mindset. Keep these in mind when choosing your
tools, and only use a tool when you necessarily need to.
Automate.
Performing mundane repetitive tasks takes time away from focusing on more
important software development activities. In The
Value of Executable Artifacts, I presented numerous techniques and tools
that can be used to automate processes and increase your productivity. The
first thing you might want to automate is execution of those unit tests if
you're lacking the discipline to run them regularly.
Building Bridges
If you're
able to pull it off and stick to your resolutions longer than a fortnight,
start thinking of ways your personal agility can help contribute to greater
team agility. For instance, if you're writing tests but know that other members
of the team are not, explain to them the benefits you've realized through unit
testing and encourage them to experiment. Let your ability to refactor easily
and the increased quality of your code speak for itself. Pair up with skeptical
developers and let them experience the value of unit testing with you. If
you've discovered an aspect of development that benefits greatly from
automation, share it with the rest of the development team and show how it's
helping increase your productivity or the quality of your code.
In less
agile environments, once you've increased your personal agility, work with project
management to grow these ideas within and throughout software development
teams. For instance, maybe you've realized a great deal of success with
improving the quality of your code and design through the use of static source
code analysis tools. If that's the case, perhaps there is opportunity to work
with project management to leverage the results team-wide and forego the waste
that often comes with emphasizing traceability. Regardless, once you've
increased your personal agility, spreading your wisdom, however challenging, to
other members of the team is especially gratifying for both you and your
customer.
The New
Year is upon us, and with it comes the opportunity to improve. By making a few
simple adjustments and adopting some proven practices, we can create an
opportunity to excel. And once we've improved ourselves, possessing the resolve
to spread your wisdom throughout the team can be incredibly rewarding.
About the Author
Kirk
Knoernschild is Senior Technology Strategist at TeamSoft, where he leads based on his firm
belief in the pragmatic use of technology. In addition to his work on large
development projects, Kirk shares his experiences through courseware
development, teaching, writing, and speaking at seminars and conferences. Kirk
has provided training to thousands of software professionals, teaching courses
on UML, Java J2EE technology, object-oriented development, component based
development, software architecture, and software process.