How Did You Write That?
A few years ago, one of my friends was playing a little Windows Forms game I wrote based on the Mastermind board game (in fact, the game once appeared as a download in the first incarnation of this very blog in 2007). Another friend saw them playing the game and asked “What is that?”
“Just a game, you have to guess the correct colours.”
“Where did you get it from?”
This was my cue to chip in smugly with “I wrote it.” The response I got surprised me.
I don’t get how you can just write an app. How did you write that?
Erm… I just did. My attempt to explain how I wrote it was a garbled mess of words like class, object, C# and code. I did not get a response.
After a while working as a programmer, you get used to responding in a certain way to new people asking what you do. You don’t go concrete and say “TDD using C# .NET and NUnit”, you go abstract and say something like “I develop software for X company which helps to solve Y real world problems.” They’re still non the wiser, but at least they feel that they should have understood the words you just said. That’s fine for the one off encounters, but when someone digs deeper and wants to learn quickly what you do that actually produces the software, it’s a little more difficult.
We forget that what we know has been gradually soaked up over many years. I’ve been doing this stuff full time for nearly 10 years, and I still struggle to explain the lower level details of what I do or why we do it that way. Based on Einstein’s suggestion that if you can’t explain something to a six year old, you don’t understand it, I understand very little of what I’ve done for a living for the past seven years.
Rather than focussing on details such as classes, code and languages, much of the time an analogy can be used to explain what goes on. We have an abundance of analogies in Software Engineering, but none of them quite fit correctly.
McConnel in Code Complete seems quite fond of the construction metaphor which likens building software to building a house (or the most appropriate structure for your particular project). That describes the process for something with a definite beginning and end with a well defined plan. However, on many Agile projects we deliver software incrementally. We’re free to backtrack or implement new requirements that weren’t foreseen at the beginning. If you were delivering a house using Agile processes, you’d deliver a shed in a couple of weeks which people would move into. Then maybe add a couple of ground floor rooms over the next couple of weeks, then an upper storey, then the plumbing, maybe a roof terrace. Then feedback from the occupants might reveal that they’d prefer a South facing roof terrace, another floor and some of their windows moving around.
Those aren’t the types of things that could be accomplished in the real world, not without extraordinary expense at least. However, those are the types of things Agile programmers are metaphorically used to. You wouldn’t watch a builder moving around a wall in a house several times before being happy with it – it’s been decided up front. I think that’s what differentiates software development of a typical business application from construction of a typical house. The amount of up-front planning for a house tends to be much greater than that for an agile software project. Decisions have to be set in stone, as it were.
Hunt and Thomas in The Pragmatic Programmer seem quite fond of the gardening analogy. I’m quite fond of it too. However, when suggesting to a friend that programming was like gardening, I was laughed at. I can see why. Code doesn’t just grow on its own (although it may seem that way sometimes).
If you think of programming like gardening, you have to think of the programmer in a combined gardener/Mother Nature role. Declaring classes and major components is like doing the planting, and writing the code is like growing your plants.
For gardening, the amount of up-front design required is similar to programming. You start with an overall architecture and then figure the rest out while you’re doing it. Sure, where you plant things can be decided ahead of time, but are you going to decide how many branches your trees have? How many leaves they have? Do you even know if it’s possible to grow a tree with that arragement of branches? No – you have to get on with it and figure out the details as you go. Sure there are details that can be figured out later in the construction mataphor, but with gardening and agile software development the number of details that can be left until later is much larger.
I like this way of thinking about Agile development (and is supported by Freeman and Pryce in Growing Object-Oriented Software Guided by Tests which introduces terms like “budding off”), but it means little to someone who isn’t a programmer. It’s hard to get your head around this “Mother Nature” role. But it perhaps indicates why this stuff is difficult to explain. If someone asks how you would write some application, the best you can do is guess at an overall architecture and then say you’d figure out the rest as you went along. You have to create a solution to a problem before you know what the solution’s going to be. It’s a wicked problem.
Ultimately, in order to really understand how to write an application, and why we go on about gardening and construction, you have to go out and do it.