In case the title of this article is confusing to you, BDUF means Big Design Up Front. It essentially means that you will hammer out a complete design up front, before you being to create your solution. The reason that I bring this up is because of Glenn Block’s ALT.NET Criterion post. In his post he mentions “Not doing BDUF” as one of the ALT.NET principles, and I think that making the distinction between doing *Big* Design Up Front and Design Up Front is very important for developers to make.
A lot of developers think that agile development represents doing no design up front. That we will figure out what we want to do and then just jump right into coding it without any concern for what we are going to build. Then we will just come back later, refactor the whole thing, and voila, instant working application. Well, it just doesn’t work that way. I always like to say that if you have one opinion on one extreme, and another on the opposite extreme, then the truth is always somewhere in the middle. Agile development and “not doing BDUF” is all about finding that sweet spot of trying to decide what you are going to build, without getting bogged down in the details that are better left to implementation. I can’t remember who wrote it, but someone said “if you are going to write a spec that is so detailed that the code could be written from it, then you might as well just execute the spec”.
So, why should we be avoiding BDUF? To people from a lot of industries BDUF may make perfect sense. You better believe that BMW engineers are going to design an entire car before they start building it. Now, they may build subsystems independently, but they are going to create the design for the entire car before they start manufacturing the car. I mean, if they create the seats before they design the car, then how do they know that it is going to fit inside the car? In the world of physical parts and manufacturing this seems to be a fairly good rule. You really should have a fairly solid plan about what you are going to build before you start producing any part of it. Well, it is a good thing that programmers don’t operate in the physical world. We may have to deal with the interfaces on two subsystems, but we are able to build subsystems more segregated than these. In fact, we will often aim at our subsystems being black boxes.
So, what do I mean by black boxes? Well, a black box in software development basically means that we have an input and an output, but we know nothing about what goes on inside of the box. Another way of saying this is that these sub-systems are orthogonal. They are completely separate and making changes to one will not affect the other. In the physical world, you could design the interface between the engine and the drive train, then you could design the interface between the drive train and the axles. You could even design the interface between the engine and the frame. So, now you have the entire drive subsystem, but you could still get in a situation where the engine doesn’t fit inside of the body. This is because even though the engine and the body don’t have an explicit interface, the physical dimensions of the body affect the design of the engine.
In software we still have these sorts of indirect constraints, but our medium is quite a bit more malleable than steel and manufacturing lines. If we design two sub-systems and find that there is an unavoidable indirect constraint, then it is much easier for us to change our design. But just because we can change it, should we? I mean, if BDUF works for complex systems like automobiles and airplanes then why can’t it work for our software systems?
One word, “cost”.
The systems that developers are asked to build are often vastly complex, and the resources that are provided are often quite meager. If we had a huge amount of resources, then you might have the ability to do a big up-front design and then to analyze this design to iron out the details that can be the downfall of the waterfall model. This takes a lot of effort though, effort that is often a waste. If a decision can be made further down the road, then it is going to be made with more available information. This is the concept of Last Responsible Moment. This is the key to what BDUF lacks. When designing an application you are making assumptions. You may not even realize all of the assumptions you are making, but you are making them. And when those assumptions end up being wrong, then your design is wrong. Unless you have the resources to analyze and test all of the assumptions you make in your design, then you are likely to end up with a design that has flaws. Flaws that could have been avoided if you put those decisions off until you had to make them.
The important thing to note though is that we still want to do design up front. In fact we always want to be thinking about design. At the start of a project it is desirable to do some design up front. You want to have a clear picture of what business value you are trying to attain, and a more blurry picture of how you want to attain it. As you start to fill in the picture of how you are going to attain your business objectives then things will start to become more and more clear. It is very important that you realize that the value comes from not knowing all of the details. To many business people this may sound terrifying, but how many times have tools been picked at the very beginning of an application lifecycle (along with thousands of dollars spent), only to realize that the tools won’t do what you wanted them to. Or the tools originally did what you wanted them to, but now your needs have changed. Then you are forced to spend resources to force the tools into your particular need, but even then you may end up with a fragile system.
So what does all of this boil down to? Design your application. Being agile does not excuse the need for not planning ahead. Being agile means that you are going to respond to change, and putting off decisions can allow you to more easily make better decisions. Next time you are on a project and during the planning phase someone picks a vendor to fill a specific need, ask them to put the final decision off until that part of the application needs to be built. The vendor will still be there when the software is needed, but if you put off the purchase, then you may find that you need different software or you don’t need it at all.