Designing in Agile World

Introduction

Softwares, once you strip away all the layers of abstraction, is really just a big pile of numbers. In fact, even those numbers are abstractions for bunch of electrons moving around. We partly human beings are just incapable of thinking about software in those terms however. Reality is just too complicated. We have to think in some sort of metaphor, in terms of pictures.

We all have mental pictures of what we’re building as we built it off course. When it comes to a tree or linked-list or a hash table, we think about a picture in our head, not about the underlying numbers and of course, if we are all using the same pictures, we can use those pictures to communicate with each other. This practice is inspired from the architecture of buildings hence called software architecture.

Architecture

When we are making a building, we start with a detailed plan. In other words, we design the entire architecture before we start building. We do that because experimentation, when it comes to buildings at least, is just way too expensive.

We can’t just build the building and then start tearing out and replacing the parts that we don’t like, we’ve got to get it right the first time.

Thinking that building software is like building buildings though, has created a lot of problems.

Software isn’t made out of concrete and rebar. For example changing a part of code that you don’t like is trivial and working in a way that just pretends that its not, is just not gonna work. It took us a long way to come to that realization however.

In early 90s we thought that software should be created like buildings. We’d start with a detailed picture, a big upfront design, usually created from enormous requirements document that you put together before you design anything. It might take months to put together the requirement documents and then the design. We’d then try to build exactly what we had drawn. In fact, the thinking at the time was, the architect was doing the real thinking here, and the code could just be written by monkeys.

Now moving forward to the present, now a days, we think in terms of agility. We’re working in an agile world where we don’t do a big up-front design.

Once we drill down into agile, one of the things that we notice that its all about communication. Two or more people conversing in front of a white board. But what exactly are those conversations?

In a waterfall model, we’d have most of those conversations at the beginning of the project, when we were putting together that giant requirement document.

Designing in Agile

In the Agile World, we spread those same conversations over the entire development process. It’s important to notice though its the same conversations, they are just spread out. It’s a mistake then to think that we’re not doing any design inside Agile.

What we are doing is incremental design. In other words, we’ll do the design bit-by-bit over the course of the whole project. We build the code incrementally too and we learn things as we do that.

Now if we had a big upfront design, the things that we learn might render that design useless. But in the Agile world we don’t have that. Instead, we defer making decisions until we have enough information to actually make the right decision (delay until last responsible moment). That way when it come time to make the decision, we can leverage everything that we’ve learned up to that point.

We still have to think about the structure though and coherence, and to do that, we have to be thinking about the larger system. So that brings us the notation of “useful ambiguity“. We want to design in a way that it is ambiguous enough that as we learn things, we can incorporate what we’re doing into the design without impacting the design in a serious way.

We want the design to help us think about structure, but we don’t want it to force us to commit to a specific implementation. So when we draw a picture of design, we want it to be a little bit fuzzy. We don’t want it to be a programming language. We want it to be a rough sketch that we can fill in as we work.

UML, not so Unified

Back when we were working this way, there were several notations e.g. Boch notation, OMT (which leads to UML later), people used to draw those pictures.

UML had a few problems from the day one though. The first issue is that it wasn’t ever really unified. Also UML was so detailed that it was effectively a programming language (remember our monkeys analogy earlier). As a consequence, we were really writing the program twice. Once in UML and once again in your choice of programming language. So there were some concerns about it.

So instead of doing everything by the book, we can actually use the good bits of UML to support our design process. Our design docs should be not that detailed that it actually start feeling like a programming language.

What’s Next

So, what are those good bits of UML and how we can have more lightweight and balanced design approach as part of our software design and development practices? We’ll cover such topics in more details in coming days. Stay tuned!