August 2, 2012

...Learn TDD with Codemanship

Back To Basics #3 - Software Development Is A Learning Process

This is the third in a series of ten posts attempting to explain the basic principles of software development without resorting to buzzwords, brand names and other things that begin with "b", in the hope that those beginning their journey towards becoming a software developer can maybe get to grips with the fundamentals before our culture pollutes their minds.

Everything in life is, to some degree, an experiment.

Every song a composer writes is both an object to be enjoyed in itself, and also a step towards writing a better song. And every omelette I cook is both dinner and a step towards cooking a better omelette. But we'll talk about breaking eggs a little later.

With each attempt, we learn and we're able to do it better the next time. This is a fundamental component of our intelligence. We're able to train ourselves to do extraordinary - sometimes seemingly impossible things - by doing them over and over and feeding back in the lessons from each attempt so we can improve on it in the next.

Software's no different. Our first attempt at solving the customer's problem is usually pretty crappy. Maybe even as crappy as my first omelette.

When we create and innovate, we're doing things we haven't done before. And when we're doing something for the first time, we're not likely to do it well as we would on the second attempt, or the third, fourth of fifth.

Software development is a process of innovation. By definition, we're doing things we haven't done before on every new product or system. So we must expect our first omelettes to be a bit crappy, no matter how experienced we are as programmers.

Now, I don't know about you, but personally I've got a bit more pride than to make my customer pay for a crappy omelette.

In software development, the way we get to good omelettes is by iterating our designs until they're as good as we can make them with the time and resources available.

Sticking with the culinary metaphor, we cook an omelette. If it tastes good to us (we'll get on to tasting our own dog food soon enough), we get the customer to try a bit. If they love it, great. We can move on to the next dish they've ordered. But if they don't think it's just right, we seek feedback on how we can improve it. And then we act on that feedback and cook them another omelette.

Rinse and repeat until the customer's happy.

Other books and articles on software development principles often linger on "how to get the design right" and will fixate on all sorts of hifalutin ideas about "user experience" and "modularity" and being "domain-driven".

But of all the design principles I've applied in 3 decades of programming, the most powerful by a country mile is do it again until you get it right (or until you run out of road).

It is nature's way of solving complicated problems, and - to the best of humanity's knowledge - it's the only way that really works.

In practice (let's debase ourselves momentarily to consider the real world), we iterate our designs until they're good enough and we can move on to the next problem. Our customer has some rough idea of what this solution is worth to them, and therefore how much time and resources are worth investing in solving it. We could chase perfection until the end of time, but in reality we find a compromise where the solution we end up is good enough.

And we don't really start from scratch with every iteration, like we would with omelettes. Typically, we take the program code from one iteration and make the necessary changes and tweaks to produce a new, improved version. Unless the first attempt was so off-the-mark that we'd be better off throwing it away and starting again. Which does happen, and why it's highly advisable not to use all your eggs in that first omelette (so to speak).

Many among us believe we should create the simplest software possible initially to start getting that all-important feedback as soon as we can.

The one thing we should never do is assume we can get it right first time. We won't. Nobody ever does.

An important thing to remember is that the shorter the feedback cycles are when we iterate our designs, the faster we tend to learn and the sooner we converge on a good solution.

The problem with complicated things like software, music and omelettes is that it can be very hard to isolate one part of the problem from all the other densely interconnected parts. It may sound like the kick drum is too boomy in the mix, but that could be because the bass guitar is actually too quiet. It may taste like the omelette needs more salt, but that might be because it really needs less strawberries.

As we iterate our designs, when we change too many variables between each new generation it can become very hard to seperate the wood from the trees in identifying which of those changes doesn't really work. If we change just one variable and make the omelette worse, we know which variable we shouldn't have messed with and can easily revert back and try something different.

Therefore, another important thing to remember is that this works best when we learn one lesson at a time.

So we learn faster and we learn better when we rapidly iterate and change less things in each iteration.

Posted 5 years, 7 months ago on August 2, 2012