Programming is Not “Construction”
Lots of people who have read Steve McConnell’s celebrated book Code Complete are living with the impression that programming is, or ought to be, like constructing buildings (civil engineering). After all:
* an architect works out a design, then draws the blueprints of the building, much like a software architect
* you generally don’t make your own bricks and nuts and bolts, you reuse ready-made components, just like we’re supposed to reuse code in libraries
* there are layers of abstraction: an architect describes a building in more general terms, but the bricklayer has to have precise and low-level instructions on where to put the bricks. Various levels of foremen and managers mediate between the two extremes. In software, you have layers of compilers and code generators that translate a high-level design into binary code.
This looks reasonable.
Only it’s not. Programming is fundamentally not like construction.
* A building’s functional requirements are simple and stable: it has to stand, and it has to provide shelter and adequate sunlight. All the rest is fluff. By contrast, the functional requirements of software are very complex and often changing.
* That’s why software has to be malleable. In computing, we have a distinction between hardware and software precisely because hardware is _not_ malleable.
Well-factored software has to change little when requirements change only a little. By contrast, constructions are anything _but_ malleable. If you want to make ’small’ changes to a building, like, say, move a wall 2 metres away, it will cost you dearly, or it might be outright impossible without tearing down the building and starting from scratch.
Actually, construction has more in common with computer hardware than with software. Code Complete would be a great book, if you substituted ‘hardware’ for ’software’ all over
* Software simply does not have that many physical constraints and limitations to deal with. When you’re building, you’re bound by the laws of gravity, by the resilience of your materials, by the shape of the ground, etc., not to mention the city planners
By contrast, in software there are little such hard and fast constraints. Hardware has grown cheaper and more powerful, and will continue to do so. The times when your app had to fit in 640K of RAM are long gone. Most software you’ll ever work on will _not_ push the limits of available hardware.
* And there are lots of other counter-arguments, e.g. in this kuro5hin.org article.
“Metaphors are heuristics, not algorithms. As such, they tend to be a little sloppy” admits McConnell. However, I’m mystified why he has chosen maybe the most monstrously sloppy metaphor to describe software development. By the end of Chapter 2, I was literally cringing.
But that isn’t all.
* The book claims to be for “Programming Experts”, but the tone of the writing seems fit for fourth-graders with severe dyslexia. The unfunny pictures don’t help, either.
* Dynamic languages like Perl or Python are misrepresented, if at all mentioned. The author disdains Python, for example, because it doesn’t explicitly support… named constants. Go figure. That’s like complaining that your new digital watch doesn’t have a winding knob.
* The book works under the assumption that most of its readers are building intense-load mission-critical software systems, like nuclear bomb simulations, or chemical plant process control software. NEWSFLASH: you aren’t. If you are, you’re reading the wrong book anyway. If you aren’t, but would like to be, you should be reading SICP, for example.
In conclusion: if you’re a new or intermediate programmer, I recommend that you skip “Code Complete”. It will teach you the wrong way to think about software.
A good introduction to software best practices, one which I warmly recommend, is The Pragmatic Programmer by Dave Thomas and Andy Hunt. And if you’re after a deeper understanding of general and timeless principles of software architecture, you will find Eric S. Raymond’s Art of Unix Programming particularly enlightening.
But the number one advice is: get coding! Write code, read code written by others, and learn your craft by doing it. Don’t bother searching for metaphors