Software development is an amazingly complex enterprise. On the one hand, we have the inherent complexity of getting pieces of silicon to do our bidding and 50 levels of hardware, networks, systems, and frameworks to coordinate. On the other - humans. And those come with relationships, ambitions, visions, and fears.
To get things done reliably, as an industry, we came up with a host of patterns and ideas, big and small. DRY, KISS, Clean Code, Clean Architecture, Design Patterns, TDD, Agile, Software Craftsmanship... and so on and so forth. There is, however, one useful perspective that's even one level higher - let me introduce you to Mental Models.
A mental model is simply a representation of how something works. We cannot keep all of the details of the world in our brains, so we use models to simplify the complex into understandable and organizable chunks.
At first sight, it doesn't seem to be an extremely revolutionary observation. Yes, we keep a simplified version of reality in our minds; tell me something I didn't know.
I find the lens of mental models to be an extremely handy tool. The overall framework, as defined on Farnam Street (which you can see linked around my previous posts quite often), seems obvious - find the big cross-domain concepts, understand them and use them daily. The catch comes in work required since this is pretty much a life-long process.
So why even bother? I feel we tend to get overfocused and lost in specific topics or trending approaches in IT. When discussing microservices, DevOps, agile, or SCRUM, you can feel the peer pressure and FOMO. Far too many teams follow along and drive their agenda with hot blog posts or the most recent Gartner materials.
Looking at this from the perspective of mental models is a chance to take a step back and evaluate whatever we are doing from one level higher - hopefully noticing the forest surrounding the current tree in front of us. And as a side bonus, you have a well maintained toolbox of cross-domain tools to apply when needed.
Few relevant examples that stand out for me:
TDD, A/B testing, monitoring, code reviews, and retrospectives - all fall under the general model of Feedback. Looking at those from the perspective of the feedback loop and control engineering principles around it, what would you do differently? Is the feedback loop working for you? Is the information timely and accurate?
Second Order Effects - a lot of the things we do can have positive first-order effects (we shipped without postponing a deadline) and negative or deadly further consequences (code became a mess, and we are now moving at a snail's pace). Having this model embedded in your thought process makes you more likely to notice the problem before it materializes and gives you plenty of ammunition to push back or at least plan mitigation of negative consequences down the line.
- I've seen it argued that it's just sensible analysis and planning, but I find that having a common language and model to use in tradeoff discussion is extremely important. Asking explicitly "What will be next order effects of this decision?" usually yields different answers than "What will be the consequences?"
Antifragility - is the system we are building fragile (fails with little push), robust (can tolerate a lot), or does our process make it better with each failure (antifragile)? How can we use the practices we are considering to get closer to antifragility?
The cited FS guide is an excellent starting point with a broad overview of 109 mental models split into different areas (e.g., Human Nature, Physics, and Numeracy).
Check it out here