Code Complete Review – Chapter 2: Metaphors for a Richer Understanding of Software Development
This post will provide a brief overview of the 2nd chapter of Steve McConnell’s Code Complete (2nd Edition). If you haven’t already, please first read my Introduction to the Series post. If you missed the review of Chapter 1, you can check it out here.
Good metaphors often provide insight into difficult or obscure concepts by comparing them to things we already understand. You will, no doubt, encounter many metaphors related to programming and software development in general. The goal of this chapter is to discuss a few common metaphors in order to better understand their application to the software development process. “Modeling” is a term used to describe the use of metaphors to improve our understanding. The properties of a good metaphor, or model, are 1. Simplicity, 2. Relevance, and 3. Breadth of the topic it explains.
"The power of models is that they’re vivid and can be grasped as conceptual wholes."
McConnell elaborates a bit on the difference between an algorithm and a metaphor, explaining that a metaphor is more like a heuristic. The primary distinction is that an algorithm provides explicit instructions on how to achieve a task, while a heuristic sheds light on where to look in order to assist in figuring it out for yourself. Considering the range of challenges encountered when programming, providing specific instructions (algorithms) on how to solve each and every problem is unfeasible. Metaphors, on the other hand, can provide general guidance on how to approach and understand a range of programming activities.
"The person who uses metaphors to illuminate the software-development process will be perceived as someone who has a better understanding of programming and produces better code faster than people who don’t use them."
It’s important to note that some software development metaphors are better than others. Let’s dig into a handful of common programming metaphors to see what he means.
The 1st metaphor discussed is what he terms “software penmanship,” exemplified in the phrase “writing code,” which likens programming to (surprise, surprise…) writing. The notion of writing a letter, for example, conjures images of sitting down without any preparation, banging out the letter in one sitting, crumpling up and tossing a page with too many errors on it, and mailing it out once you finish, never to be seen (or modified) by you again. None of these associations translate well to the software development process, with the possible exception of very simple, straight-forward projects.
Although I personally haven’t heard this one before, the 2nd metaphor he discusses is “software farming.” Granted, while growing crops on a farm involves more planning than writing a letter, many concepts associated with farming don’t fit well with software development either (e.g., fertilizing, land management, harvesting). He notes that the one common notion applicable to both farming and programming is the importance of incrementally “growing” the farm/software, a bit at a time. Despite that similarity, however, there are better metaphors to illustrate the importance of incremental growth in software development.
Oysters & Pearls
One of these “better” metaphors for understanding incremental growth is an oyster creating a pearl, starting with a single grain of sand and slowly adding to it over time. The term used to describe growth by slow incrementation is "accretion," which fits well with how software should be designed, built, and tested.
When you think of construction, such as building a house, you probably envision some planning process or blueprints, as well as the various stages involved in the building process. Many of these stages have correlates to software development.The image of “building” software is more useful than that of “writing” or “growing” software.
"The image of 'building' software is more useful than 'writing' or 'farming' software."
Below is a list of some of the helpful similarities between building construction and software construction:
- The size of the project increases the amount of planning needed.
- Foundation and framework are developed first.
- Core structures/components are added to the frame.
- Fine tuning and optimization occur after the core structures are built.
- You often don’t need to recreate/build things that are already built (e.g., bathroom fixtures in construction, or existing libraries or interface classes in software).
- Regular inspections should occur throughout the process.
- Large projects often need to be overengineered because the cost of failure is so high.
- Similarly, the larger the project, the more elaborate the planning process and the greater the need for technical and managerial controls.
The final metaphor discussed in this chapter is the “intellectual toolbox” that gets filled with “tools” as you gain experience developing software. It is important that these tools, which you accumulate and master over time, represent a broad range of programming methodologies. You don’t want to be guilty of always grabbing a (software development) hammer and subsequently thinking all challenges require (programming) nails.
Despite the fact that some metaphors are better than others, they are not mutually exclusive. There is nothing wrong with using more than one if it helps you better understand or communicate the software development process. But because they are heuristic and not algorithmic, it is also important to not over-extend their application. McConnell states that like “any powerful tool, you can misuse metaphors, but their power makes them a valuable part of your intellectual toolbox.”
About the Author
I'm a clinical psychologist, informaticist, developer, crypto-enthusiast, and incurable tech junkie.