Being Agile is Being Efficient and Disciplined

April 13, 2012

Is agile development chaotic and undisciplined, as some would assert? It shouldn’t be. However, using frameworks and practices don’t make you agile in and of themselves. They support agility, provided that you have the right mindset and approach to your work as you make use of them.

I’ll examine the following (briefly) in this post:
  • Scrum
  • Test-Driven Development
  • Pair Programming
A huge change with agile development is that teams are self-directed. Scrum is a great framework for teams to use to manage their work, provided that teams genuinely collaborate and actively manage their work. This means more than adopting the practices, vocabulary, and artifacts of Scrum. “Doing Scrum” without an agile mindset is also known as Cargo Cult Scrum, which is the mistaken notion that ritualistic actions and artifacts will provide magical benefits. Trust me, magic is not going to happen all by itself!

The goal is to improve productivity through collaboration, and for a team to coordinate its work without the need of oversight and direction from others. Agile team members don’t maintain strict functional roles and “hand off” work to one another or to another group, their emphasis is on delivering complete features as a team. The objective is to replace these hand-offs with people who are combining their efforts by interacting, sharing knowledge, managing their work and dealing issues together to produce a valuable (to the customer and the organization) outcome.

Good teams also make use of practices such as Test-Driven Development and pair programming that are designed to support agility, allowing them to maintain engineering discipline while streamlining the work.

Test-Driven Development (TDD) is about creating an automated unit test before the code is written. This changes the order of the traditional approach to work, with the goal of improving our work and making sure that we discipline ourselves for being productive over the long haul, without making short-sighted, short-term “productivity” sacrifices.

TDD enforces the discipline of creating automated unit tests on both the developer and any manager who might be inclined to push for shipping a feature now, sacrificing the creation of automated unit tests that are typically one of the long-term quality objectives many organizations have. And we need automated unit tests! They enables us to refactor the code with confidence, supporting the ability to continually and productively evolve and improve the design as we move forward.

Notice that I didn’t say TDD drives design, but rather that automated unit tests supports our ability to evolve and improve the design – something else that we need to do with agile development. It’s part of our overall commitment to quality and technical excellence.

Interestingly enough, while TDD doesn’t drive design, it does help to enhance it. The act of writing a test first forces the developer(s) to consider how the code will be called, and as a result the interfaces become a little more understandable. As a practice TDD also can improve the testability of the code because developers are writing tests beforehand, not after, and the goal is to create automated tests that cover the code as completely as possible.

For these reasons, Test-Driven Development is superior to what Jeff Langr referred to as Test-After Development, or TAD – as in a TAD too late in one of his 2008 blog posts.

Of course, TDD alone won’t solve all of your problems. Good design is important to the long-term viability of any software product. Good software design contributes to having fewer defects to contend with along with allowing new features to be added in reasonable time frames. I’ve argued that source code should be treated as an asset, not a liability (and I acknowledge that there are those who will disagree with me).

I readily agree that poorly-designed code is a liability because the level of difficulty in updating poorly designed code with new features can range from difficult to impossible. Poorly-designed code raises the bar in terms of the time, effort and level of concentration required to update it. And it usually requires a lot of regression testing to make sure that “unrelated” features weren’t dinged in the process.

Pair programming can help here. Pair programming should strengthen the design because two developers are discussing the current code base and what needs to change to support a new feature. You should seek to accomplish a combination of a design/design review along with a code review as a benefit with pair programming, with less aggregate time spent by performing those activities separately.

Pair programming has other benefits as well. My top five benefits of pair programming:
  1. Improves design quality.
  2. Reduces defects.
  3. Accelerates problem-solving.
  4. Broadens the understanding of the code base.
  5. Increases job satisfaction.
I’ve covered Scrum, Test-Driven Development and pair programming as they relate to agile development. You can use any of these to obtain an incremental improvement with whatever approach to software development that you are using today, without question.

From an agile context, it pays to look a little deeper, to understand how you can eliminate or reduce work in process queues, to collaborate or apply techniques that reduce overhead and maintain or improve your overall professional discipline and achieve long-term productivity gains. That’s what being Lean and agile is all about.