Building the Right Mental Model for your Applications

tolulope duyile
Red Squirrel
Published in
8 min readFeb 1, 2022
Photo by engin akyurt on Unsplash

Have you ever worked with a senior engineer? Had a discussion over lunch about the codebase you’re both working on or a problem you’re trying to solve, and they immediately pointed to the files that you need to make changes to, sometimes, even referencing the exact lines?

And then gotten a detailed pseudocode on the changes you need to make? Always impressive, right?

You’re convinced it must be some sort of super power and you tell yourself that sometime soon in the future, you’ll become that proficient.

True, your proficiency does get better with time, but every skill can be studied, broken down and reduced to reproducible patterns.

Before we dig further, I’ll take a quick detour to mention an especially important concept: mental models.

What are Mental Models?

A mental model is a representation of how something works. They are how we make sense of seemingly vague concepts, more often than not, done by mapping it with already understood concepts. For example, zealous techies sometimes use expressions like, “Uber but using bikes” or “Tinder but for divorcees” to get their audience to catch on quickly to the idea. To make the communication of intent faster, leverage was put on previously understood concepts.

Why?

Humans typically optimise the processing of new data by mapping out the new data with pre-existing information stored in the brain, concurrently building on the set of relationships between them.

That is typically how mental models work. Building layers of information on pre-existing layers of information.

Now, back to the senior engineer case study. How was anyone able to accumulate so much knowledge of the application’s codebase such that it seemed like it was single-handedly built even though there were over 15 (just picked a random number) engineers working asynchronously on the codebase?

Here’s how:

Understanding the Business Model

Software companies, like any others, are doing business by providing value to their customers. As technology itself has no value, companies need to be able to create and capture value through an effective business model. The concept of business models captures how a company functions and creates value, and it describes, for example, a company’s value proposition, its activities, customer relationship, revenue model and resources, and is critical to success in the digital world.

I found those excerpts from an article I read a while ago whose source I can’t seem to remember, but something that stood out for me was the statement, “technology itself has no value,” and I will explain why, perhaps by expanding in my own words:

Technology itself has no value until it is applied to solve a problem.

Newer engineers get into the wide and interesting world of software engineering and become so caught up in the tools, forgetting that they are just tools, and a tool is only as useful as the function it was created for. A craftsman always loves their tools, and that is ok. They are what they use every day to perform magic. Terrible tools can make your work experience suffer and can inadvertently lead to a not-so-great end product for your users but a good tool without proper focus on the users’ wants or needs can create a really great product that your users do not need.

Key phrase: your solution is as valuable as the problem it solves.

Understanding the problem domain is always the first step to being better equipped to proffer solutions. I read somewhere that the best startups are built by people who are trying to solve their [personal] problems. It is the extra skill required to be successful at your role. Your ability to write efficient code isn’t as important as knowing what problem your efficient code is trying to solve, what phase of the business process it automates, and how it helps achieve the business’s target.

Like I always tell people, nobody is paying you to write code, you’re being paid to solve problems [using code].

Saying that you’re not being paid to write code might seem like a straightforward statement, but it can also be elusive. It can be buried in all those feature stories, the PR reviews, the refactors, the performance optimisations, all the really smart tech processes, so much so that you forget that they’re all a means to an end — solving actual business problems. Understanding this however simple concept already positions you at a vantage point to be a more resourceful software engineer, as you don’t just see lines of code, you see how they fit into the organisational structure, business model and targets.

Understanding the Data Model

Data models are perhaps the most important part of developing software, because they have such a profound effect; not only on how the software is written, but also on how we think about the problem that we are solving.”- excerpted from Designing Data Intensive Applications.

We are continuously building applications that are highly data-intensive: storing data, sending data, retrieving data, and processing data. Typically, this application data is modelled to mirror the problem domain and it contributes to determining the overall application architecture. The way I see it, the data model is basically the engineering interpretation of the business model. As with every engineering solution proffered, the data model is always designed with trade offs that creep into the application logic, and not understanding these trade offs or the data flow will keep you building without foresight. Although PR reviews can help fix some of these issues by adding insight, a lot of times even this isn’t enough. Here’s why:

Each problem space typically has various solutions with different trade offs. Without proper understanding of the data model/data flow in the application, you cannot properly analyse all your options and this sometimes means that you might go with the less optimal solution.

Now, we are going to reach for a bit and assume that the team synchronisation isn’t at its peak, so the reviewers do not have any pre-context to what problem you’re trying to solve. On a very busy day with a lot of PR reviews to go through, your reviewers immediately adopt your solution’s approach (which, like we alluded to earlier, might not necessarily be the best approach), go ahead and check for other important factors like readability, correctness, performance and give some feedback. Here’s the thing, your solution wasn’t wrong, it works, even got merged, but there is a problem — it was proffered without knowing all the variables ahead and unless you are just exceptionally lucky to arrive on the optimal solution, you will have merged in solutions that will reduce the robustness of the codebase. This might not present a problem right away, but as the codebase increases, these leaks begin to creep out.

Macro Architectural Design

“Even when you think you know everything, writing good software is hard enough … it becomes that much more difficult if you’re confused about the big picture”Ryan Prinz

I had a conversation with Ryan while writing this article and that statement left an impression on me. It is quite possible to consistently raise PR’s, do code reviews and not totally understand the overarching architecture of the application. I would know — been there, done that.

One very underrated upside to having a mental model of the application architecture is not just knowing where to place stuff and ensuring boundaries, it’s in helping you think better, and wholly too.

The quality of our thought process is proportional to the models in our head.

Over the years, architectural patterns have been developed from building various softwares of different scales and learning what works. This has largely helped engineers create a mental model of their application structure and data flow. Redux and the clean architecture are one of my favourite architectural patterns for making sure that the increasing complexity of the problem being solved does not translate into complex unstructured code (though, I do not use them nearly as often but I must admit that the ideas they communicate are sound and solid). Also, they promote the unidirectional data flow across layers which I think is brilliant and cognitively easier to reason about.

These architectural patterns help you create a mental overview of the design structure of the codebase on a high level without having to get into the weeds. The ability to take a step back, look at (and also understand) how data flows between layers is an underrated test of how much of what’s going on you understand.

One quick flag that I’m losing my mental model of the codebase overview is when I look at the folder hierarchy and can’t immediately tell what to expect inside the files from the file structure. It shows a deficit in my mental model of the codebase and signals for some re-arrangement or possibly just a renaming.

Micro Architectural Design

“The hardest bugs are those where your mental model of the situation is just wrong so you can’t see the problem at all.” — Brian Kernighan.

Earlier, I spoke about engineers focusing on their tools and how it’s very important to be more fixated on the problem space it’s being applied to. Here, our focus is on the tools we use, making sure we have a firm grasp of how our tools work, and creating mental models to ensure we have a vivid picture of how they work.

Code is hardly ever written without constraints and context, which gives insight into why decisions were made, correspondingly giving you a better understanding and mental model of the codebase or tool you’re working on (or with). Every portion of the code that is not clearly understood is a deficit in your mental model, increasing the surface area for bug creeps. Writing code (for large applications) is a team effort, and optimizing for understandable code is important to building a robust mental model. Comments which help with clarity of contexts are always great additions to any codebase.

Everyone knows that debugging is twice as hard as writing a program in the first place. So if you’re clever as you can be when you write it, how will you ever debug it?” — Brian Kernighan.

Excluding syntax errors, bugs are typically your best indicator of lapses in your mental model, and while debuggers are great, they mostly lead you to solving the symptoms and not the underlying problem. Being able to reason about and mentally visualize the flow of control in your code is an irreplaceable skill, as it helps you to not just address the issue but to also step out of the immediate symptom to apply your mental model of how the code works.

Building the right mental model for your application is a continuous and deliberate effort to make sure you reduce the number of “black box”, hidden contexts and potential concerns in your applications.

If you enjoyed this article, you might also want to read the Effective Mental Models for Code and Systems by Cindy Sridharan.

--

--