I recently read the Mythical Man-Month, a collection of essays on software engineering by Frederick Brooks. He writes about his observations and experiences from working at IBM and managing the OS/360 project in the sixties. The book was first published in the 1975 which, I have to say, shows in the examples. Many parts feel a bit dated now (like the discussion how to do time-allocation on a central computer). Still, if you look past the old technical references the essays contain a lot of good general guidelines and observations that are still relevant today.
One of the essays that especially caught my attention was “Plan to Throw One Away”. As the title implies, it suggests that one should throw away the first system and use the lessons learned to build the second, real system.
“The management question, therefore, is not whether to build a pilot system and throw it away. You will do that. The only question is whether to plan in advance to build a throwaway, or to promise to deliver the throwaway to customers.”
It is true that getting things right at the first go is hard. Writing the code forces you to think about all the small details, all the corner cases and other aspects that might have been overlooked in the design phase. It is not uncommon to realize in the middle coding that you would need some data also elsewhere but the design makes it hard to access or some special case turns out to be a pain to implement with the current architecture.
All this gives more insight to make better decisions and structure the code better on the next go. So the idea appears to have some merit. But to throw all away seems like a waste. Why move forward with a non-optimal design when you most likely start to get improvement ideas as soon as you start coding.
You shouldn’t. The modern approach is to use iterative development.
Brooks also later wrote that he now considers the original idea to be wrong.
“This I now perceived to be wrong, not because it is too radical, but because it is too simplistic. The biggest mistake in the ‘Build one to throw away’ concept is that it implicitly assumes the classical sequential or waterfall model of software construction.”
What works best for me is to first write something that work. The structure might not be final, there might be duplicate code and everything is not tidied up. But importantly the code works. I also like to write tests early. I’m not a TDD purist so I might not write the tests before the functionalities. But anyway, I like to write code and tests side by side.
It is also a good idea to start refactoring early, and the tests act as a safety-net when you do so. So you can transform the first system into the second “real” system on the fly by refactoring continuously. Writing tests early also steers towards better design decisions and helps to break dependencies because the code needs to be able to run isolated on a test harness.
So, for me “build one to throw away” is really “build something that works and refactor” instead.
For me, above all, the essays in the Mythical Man-Month give a perspective how much software development practices have evolved from the early days. The way we craft software today is so much different, and with all the modern tools and languages, so much more efficient than before.