
Old-fashioned approaches to creating software often encourage us to think of the activities involved as stages or phases in the process: the design phase, the coding phase, the testing phase, the integration phase, the release phase, and so on.
This approach has some major drawbacks. In fact, many of us have found that it simply doesn’t work on problems of any appreciable complexity.
The moment we start writing code, we see how the design needs to change. The moment we start testing, we see how the code needs to change. The moment we integrate our changes, we see how ours or other people’s code needs to change. The moment we release working software into the world, we learn how the software needs to change.
Around and around we go, feeding back our lessons into a never-ending continuous cycle of designing, coding (which I might argue is also designing), testing, integrating and releasing. The lines between these activities become very blurred. If I’m writing a failing test in a test-driven approach, am I designing, or am I coding, or am I testing? When I’m refactoring code, am I designing, or coding, or testing?
The correct answer is: YES.
And if we work backwards from the goal of having working software that can be shipped at any time, we inevitably arrive at the need for continuous integration, and that doesn’t work without continuous testing, and that doesn’t work if we try to design and write all the code before we do any testing. Instead, we work in micro feedback loops, progressing one small step at a time, gathering feedback throughout so we can iterate towards a good result.
But the continuous loops don’t end there. To ensure the software’s open to change, we also need to be continuously reviewing or inspecting the code. And to get the bigger picture right as the software grows – considering how the pieces of the jigsaw fit together – we need to be continuously architecting our products and systems on that larger scale.
And, finally, to be capable of doing these things well – abilities none of us are born with – we need to be continuously learning. In each nugget of feedback, we can see things that went well, and things we could do better. Rather than saving it all up for a “post-mortem” after a major release, and trying to change 1,001 things in our approach – which never works out! – we need to act on that feedback throughout the process, evolving our approach one lesson at a time.
Some, myself included, might say that if code craft could be crystallised in one word, that word would be “continuous”.
If you’re serious about building your team’s capability to rapidly, reliably and sustainably evolve software to meet rapidly changing business needs, my Code Craft and Test-Driven Development live remote training workshops are HALF PRICE until March 31st 2025.
