An Architect asks (part two)…Walking the design tightrope

In a previous post, I tackled a question from an architect friend of mine about whether it was possible to have anything worth releasing in just three iterations. In this post, I want to answer another question from the same conversation:

When we are building software with a traditional phased approach, we have  a lot of time to think about design. How do we avoid bad design if we are moving so quickly?

When you’ve been part of the Big Design Up Front school, you try to anticipate all requirements that may come your way and design for them up front, completing the design of the software before development begins. The problem with this approach is that you end up with a lot of code that you do not need, for a lot of anticipated requirements that never came to fruition, or were removed from scope as the project progressed.

When I was having this conversation with my architect friend, he assumed that I was going to propose an alternative of no design up front, but of course this approach is worse than BDUF.  Let me say that more succinctly:

For anything other than the most trivial of projects, too little design is worse than too much design.

If you don’t think about design at all up front, the best outcome you can expect from your project is a mish mash of features that probably do not hang together as a product. Your most likely expectation is to throw away lots of code and have a dead ends and false starts.

So how much design is enough design? The ideal approach is first to think about the end game for the project. What is the vision for the product / project? What would that look look like (at a very high level)? If your customer expects some upfront specifications, spend the time to create a short document using the Big Picture documentation pattern, as described in Agile Documentation by Andreas Rueping:

Problem: How can people be introduced to a project without being confronted with a deluge of technical details?

Solution: A good feel for a project is best conveyed through a description of the “big picture” of the architecture that underlies the system under construction.

Andreas goes on to describe the documentation pattern as describing the overall architecture, showing how the system is composed of subsystems and modules and explains the basics of the system’s behaviour. It also explains the design principles and the motivations that led to the design, as well as naming the technologies involved in the design. Most importantly, it abstracts over any details, technical or otherwise, that are irrelevant to an overview.

For detailed design, think about what is in the current iteration, and what you expect in the next iteration (some people call this the back burner iteration), and design for that. This is just enough design. Document your design using a wiki, and keep really detailed function and module level documentation in the tests where it belongs.

Maria Spelterini

Maria Spelterini

When designing for an agile project, you will always be walking the tightrope between too much and too little design. It’s a scary place to be at first.

When you fall off on the too little design side you will either have a patchwork quilt of requirements that are not a product, or you will throw away code and have dead ends.

If you fall off on the too much design side, you will end up with lots of detailed design, code and dollars spent on requirements that are no longer needed.

I never said this was easy – this is why we earn the big bucks, right? But, just like a tightrope walker, actually getting up there and falling off a few times will make you better at it in the long run. Over time, you will become the Maria Spelterini of Agile design.

An Architect asks (part one)…

I just had a conversation with a software architect friend, who asked some pertinent questions about agile. After a lively discussion, I thought that the best way to respond in detail to his questions was to post here. I’ve broken the post up as it got a little long!

First, a little background on my friend. He is a very talented developer who has been involved with several companies helping to define business strategy, and design and build business applications. He has embraced some agile practices at the developer level (test driven development, refactoring etc.) but has not been involved in full blown agile projects until recently. After seeing a customer’s kickoff presentation about how they intend to manage an upcoming project he had some questions for me. The first question and answer is below:

We’re supposed to have something to release in three iterations. How can we deliver anything useful or worth releasing in three iterations?

There are two parts to this answer. One about what you don’t build, and the other about what you do build.

The first principle you need to follow is Simplicity. This skill is so important that is is mentioned as one of the principles behind the Agile Manifesto:

Simplicity–the art of maximizing the amount
of work not done–is essential.

Ironically, simplicity is a difficult skill the first time you try it. If you’ve been of the school of “Big Design Up Front (BDUF)”, it’s a hard practice to let go of. On an agile project, you need to be disciplined in not building what you haven’t been asked for and don’t need, even if you suspect you might need it in the future. You need to follow the principle of You Ain’t Gonna Need It (YAGNI) all the time. Now, if this thing called Simplicity is defined so simply, why is it so hard to do?

Well, it’s that nagging feeling at the back of your mind that you ARE going to need it. Designing everything up front and gold plating requirements is comforting for two reasons.

  1. Developers love solving problems, and there’s almost nothing more satisfying to a developer than finding a general solution to a problem. The good news is that you don’t have to abandon this approach entirely; as you’ll discover, if you practice test driven development and refactoring properly, it will be easy to find a general solution to a problem when you need to find a general solution and not before.
  2. Developers worry that without a big design up front, they will have to go back to the customer with change request forms and throw away code that’s already been built, thus adding lots of time and expense to the project. These seem like realistic concerns at first glance, so let me address them:

There’s really no such thing as a change request on an agile project. Change requests exist on projects where requirements are fixed. Agile projects embrace change, and what is built and not built is entirely up to the customer. The constant feedback and communication between the customer and developer and the fact they are part of the same team ensures that feedback is incorporated early. Formal change requests are not necessary on an agile project because there is a requirements backlog where the customer can add, remove and prioritize requirements.

While it can happen that code gets thrown away, particularly if you are not practicing Little Design Up Front (LDUF), by following the SOLID principles it’s more likely that your code can evolve and change, and the tests you have in place will ensure that existing functionality is not broken by new functionality.

The second part of this answer is about what you do build. In Agile projects, requirements are typically defined as User Stories. A User Story can be thought of as a vertical slice of functionality that has value to the customer. The skill of defining and slicing up these requirements is so important that there have been several books written about it. I recommend User Stories Applied by Mike Cohn for a great introduction to this topic. Building vertical slices well requires that you practice the principle of Simplicity to ensure that you only build enough infrastructure to support your current requirements.

I’ll talk more about practicing LDUF and agile architecture in upcoming posts, so watch this space.