When you first start “doing Agile”, the focus is on getting the mechanics right:
- keep your standup updates short
- don’t over design
- remember to add tests for everything
- remember to check CI status
- only show working code during showcases
This is perfectly natural as team members strive towards Competency. Unfortunately, just as natural is the tendency to get caught up in tactics and forget to pay attention to the big picture.
After all, Agile is simply a way to manage software projects. Just like any other project management methodology, it tries to ensure successful delivery by dealing with things that cause projects to fail. Things like lack of coordination, lack of understanding, inefficiencies, etc. And although these pitfalls can trip up any team, it seems that new Agile teams are especially prone to two: risk and waste.
Agile teams often believe (quite strongly) in Emergent Design, while shunning Big Design Up Front. That is to say, they want to let the design of the system to “emerge” over time instead of planning it all out ahead of time*. The reason behind this is simple: BDUF forces you to make design choices with incomplete information, which leads to unnecessary work (“did we really need five layers to load a data set?“) or re-work (“I really wish I knew that library X doesn’t support feature Y before I used it all over the place!”).
There is a whole set of techniques at our disposal to practice emergent design: delay decisions until the last responsible moment, try to do the simplest thing first, try to avoid building things unless we actually need them, etc. These are all great and useful techniques, which should be used as often as possible. Except when it’s not possible.
The thing is, actually doing emergent design (especially on a large scale) is not trivial. Every system has design drivers that can force the implementation to go one way or another. For example, the need to expose functionality to multiple different types of consumers often results in putting business logic behind a services layer. If that design driver isn’t there, a services layer is unnecessary and probably harmful (in that it complicates things and makes the system less maintainable).
When it comes to design drivers, ignorance is not bliss. Surprises that result from uncovering design drivers too late are rarely pleasant. In the best case, you may need to do more work than you planned for. In the worst case, you may need to rewrite large parts of the system you’ve already built.
So, following emergent design principles blindly is risky because it can cause agile teams to postpone uncovering their system’s design drivers. In other words, just like doing BDUF can generate waste, not doing Some Design Up Front (SDUF?) can do the same (Yes, it may be a different kind of waste, but it’s waste nonetheless). Which brings me to my next point…
Almost by definition, Agile processes assume that there will be some waste. I mean, if you’re building something over time, learning and changing as you go along, you will very likely have to go back and change at least some parts you previously created. What makes Agile waste especially expensive is the investment in quality which Agile teams often make.
More often than not, Agile teams strongly emphasize building quality software (and if they don’t, they should). But quality is not free. Doing TDD, writing automated tests, pairing, and other ways to ensure quality all have a cost associated with them. The more tests you have supporting the code you wrote, the more tests you may have to change if you decide to significantly refactor it.
A related issue comes up when the investment in quality is made blindly. If the code you’re TDDing and wrapping tests around will actually make it to production, then the investment in quality is justified. On the other hand, if you TDD a solution that ends up being thrown away or write functional tests against something that will definitely change (such as a UI in flux), that level of investment in quality is probably not justified. It may make more sense to do a spike (or maybe even fire a tracer bullet) first to get a better understanding of what needs to be done.
Ok, Let’s Wrap It Up…
So, to summarize: uncover risk early to minimize waste. Doing so doesn’t make you less Agile (or, God forbid, Waterfall). It’s just good project management.
By the way, I wasn’t trying to consciously parrot Dan North and his Deliberate Discovery thing, but it pretty much came out that way.
* In his great book on Agile Principles, Bob Martin gives a very illustrative example of emergent design by implementing a Bowling game scorer.
You may also like:
Did you love / hate / were unmoved by this post?
Then show your support / disgust / indifference by following me on Twitter!