Mental models are foundational. They decide how we interpret information and reason about a topic. Yet mental models for writing software are immature and little discussed. Code That Fits in Your Head puts mental models front and center.
The first chapter lays out some analogies used for software and how they fall short. I’ll briefly recap these models and my own mental model.
Building a house is an old, common, and damaging mental model for software development.
The idea goes that there is an order to things. You first need to put up a frame, run utilities like water and electricity, then you can start building rooms. Building out of order causes needless rework.
A chief problem with this model is that it suggest some developers are like construction workers and there is a somewhat mechanical phase of writing code. I’ve seen this idea in practice, and it works poorly. All phases of writing software are design.
Another issue is the assumed rigidity in dependencies. Learning architecture approaches like ports and adapters showed me that software doesn’t and shouldn’t rely on some infrastructure phase. Good designs insulate components from external knowledge. Unlike houses, we can and should build the “kitchen” before deciding utilities. We can and should be able to lift “rooms” from one system and use them unchanged in a different system.
Code That Fits in Your Head also calls out the garden model of software.
This model is doesn’t consider harmful so much as incomplete. This model captures the progressive nature of and continual care needed for software. However, it focuses on reaction and says relatively little of active creation.
Engineering bridges art and science. If it could be mechanized, it wouldn’t require engineers, it’d be manufacturing. Yet the goal isn’t just expansion of knowledge like science. There is a significant recurrance of familiar and solved problems. This is a much closer model for how software works.
However, even traditional engineering disciplines are an inaccurate mental model for software engineering. In software, the design is a running product. We don’t need models to avoid material and labor costs of construction. Experiments can work alongside implementations (MVP, A/B tests, etc).
Other engineering disciplines can still impart significant lessons to software. Mark talks about checklists an signing off on each others work. Also, heuristics for encoding knowledge while also leaving wiggle room for differences between problems.
I feel grateful to have a background in mathematics, and for my early connection to the writings of Fred Brooks. Both shaped my mental model for software and prepared me for working directly with ideas.
The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination.
- Fred Brooks, Mythical Man-month
Software problem modeling isn’t quite like math either. Unlike in math, software only needs enough rigor for a computer to run the code. Math models/proofs can be arcane so long as they are rigorous. They only need to be understood once. Software models are regularly updated, so understandability is key, more like engineering designs.
The whole software process is progressive iterations of understanding the business problem. Even released code is part of refining understanding to make future updates. A developer’s job is only done when the problem is sufficiently understood such that the software no longer needs to change.
Motorcycle maintenance painted a more concrete picture for a friend of mine. The hard part of mechanical work usually isn’t replacing parts, it’s asking good questions to understand the problem and replace just the right parts.
Overall, approaching software as problem modeling has served me well. It also aligns with the model described in the Software Engineering Body of Knowledge
The mental model we use to understand software greatly impacts what we believe about software. Code That Fits in Your Head explicitly calls out several models and shows the progression toward a better, but still not perfect, engineering model of software. The engineering model meshes well with my personal model born from math and general problem solving.