An engineering organization is a system that produces a system.
But how do we describe those systems?
An engineering organization is a system that produces a system.
People often speak of groups of humans working together as something that is inscrutable.
We know from other fields that there are defaults for our behavior, especially when the groups of people are sufficiently large or under certain incentives. They become a system that we can model.
My favorite example of this is traffic. People in cars can be modeled as a fluid.1 Specifically, if you look at individual drivers, they'll tend to decrease their speed as the density of vehicles around them decreases.
A fairly poignant example of this traffic phenomenon is the following YouTube video that demonstrates the formation of “Phantom Traffic Jams”. It's worth a watch to see it in action so you can viscerally appreciate it.
For those reading ahead instead of watching, the effect is that given a sufficient density of vehicles as speed increases such that stop and go traffic becomes a wave you can actually see propagate through the cars, and so the cause for a traffic jam is itself the traffic.
If you mental model traffic not as a fluid, but with some other kind of model, you’ll likely draw some wrong conclusions about it likely behavior, and your ability to change it becomes limited because you don’t understand what’s going on.
This is a major problem that most software engineering organization face.
What does a software team actually do?
So what do I mean "a system that produces a system" in practical terms, though?
I mean that software engineering is primarily about creating systems to deliver value, either directly or indirectly. By directly I mean that sometimes the work is very direct like "change the copy on that button" or "turn that font a different shade of red" or "change the X rate from Y to Z".
But many times the work is indirect, "decrease the error rate of ABC system" or "make a thing that allows us to change X rates more rapidly." These kinds of changes are making a system more responsive to future changes or make the system more resilient while delivering value.
In fact, many software engineers would say this indirect work is the real work of software engineering, because they’re building abstractions to enable more rapid delivery of direct value.
It’s at this point where many non-technical collaborators get confused.
Why does this “indirect” vs “direct” work matter?
Let’s approach this by thinking about literal activities.
What do software engineers actually do? Most software leaders think it's fairly obvious: they write code.
Yes, but how exactly does that take place? If you have 8 people making a todo app, what exactly is each person doing during they day?
Let's take one of them and generalize their day from an average day of a software engineer. We have plenty of YouTube videos to generalize from after all, given the popularity of the "Day in the Life of a Software Engineer" format.
They all go about the same.
8am - sit down at desk, remotely or in-office
9am - standup
9:30am - open JIRA and read next ticket
9:45am - writing code
noon - break for lunch
But wait now—what does "writing code" actually mean? What happened during those 2 hours? We often skip past this description of "writing code" relatively rapidly when describing the work.
Does writing code mean actively typing out code that entire time?
Track what you’re doing
If you screen record yourself and then do it for long enough that you forget that you're recording yourself, you'll notice that you aren't typing the entire time. In fact, you're only typing a small minority of the time. The vast majority of the time you'll see yourself switching between different things you're reading.
Sometimes, but more likely what’s happening is more like bursts of typing with lots of reading. If I were to guess on an average day, it’s like 90% reading and 10% writing.
Said a different way, “writing code” happens mostly in your mind first. Understanding what the next right thing is to do and then doing it.
The constraint is hardly ever your typing speed.
For those that actually have written code before, we all think it's obvious.
But even you have written lots of code, it’s worth to take a step back and consider exactly how you’re spending your time.
do you mostly stay in one code base or section of code in 1 code base?
if you’re switching between them often, why are you switching?
how many different kinds of things are you needing to think about?
are you changing languages? why are you changing languages?
Sometimes it’s useful to map things into a physical space.
If you are moving between 3 different code bases, you can view that as getting up and mentally walking to another building.
If the programming languages or frameworks are different, then you can model that are perhaps changing out tools or physical gear to use.
As you build up an image of what you're doing, you're beginning to build a mental model in the physical world. That mental model forms the foundation in your mind of what's possible to accomplish that work. It’s a mental model that you’re using to think about your work.
Metaphor as mental model
I invoked the idea of moving between physical spaces or changing out tools. That’s an analogy or a metaphor. They’re not literally those things.
We use lots of metaphors in software engineering—technical debt, architecture, round trips. We do this to make it easier to talk about what we do, both outside our discipline, but also inside of it. The use of metaphor is necessary since software is abstract, and humans need concrete things in order to understand and more easily grasp what is being conveyed.
It’s why we joke about naming being one of the hard things in software engineering. We generally have a loose idea of what a Contract class might be. It’s suggestive of what it is. It’s why we dislike expansive names like AbstractFactoryPatternBaseClass or simple but vague ones like x.
Metaphors are like this naming effect. Our selection of a particular metaphor often restricts our ability to talk or even think about a particular problem, because human language is how we talk about our abstractions to each other. They become our mental models.
And the people who spend the most time talking about how we’re working together or what we’re doing are engineering and business leaders. While many engineering leaders and business leaders may have some model they have in their mind, most probably couldn't articulate what it is.
The reason for that is a bit complicated. Most businesses don’t invest in training their new managers. If they’re lucky, their previous manager taught them some things that were useful and recommended a book. Consequently, most of management practice is largely tradition with a sprinkling of herding behavior. If they’re really lucky, they might have had a coach or gone to some training.
Most engineering managers aren’t lucky. They’re tossed into the deep end and told to swim. They may not know why a particular approach works; they likely don’t care.2 There’s a large variety of reasons for this, and that’s largely beyond the consideration of what I’m trying to tackle in this brief article.
Suffice to say, very few business or engineering leaders spend any amount of time thinking about what could be different and how to get there. It’s largely a rational choice: if you have something that works well enough, why question it? Business or government or non-profit—you likely have people relying on you to deliver something of value. Why risk not getting it done?
As consequence, you get sports, religious, military terms smushed together with industry-specific and corporate jargon. This mixture generates sentences like:
With our conversion rate on target, we’ll likely hit our MRR goals out of the park next quarter.
That’s a real sentence that a real engineering leader might say.
It’s slapped together with disparate metaphors and generates a chimera of a mental model for what even is going on. (“hit our MRR goals out of the park?”)
We pretend that it’s a sensible sentence. (What’s a “conversion rate” and how could it be “on target”?)
The poor engineering team just nods and hopes that someone else will tell them what this actually meaning, both in terms of how they’re doing (performance), what they’re going towards (goal), and why they’re doing it (meaning).
But these three are the most fundamental things an engineering or business leader can do. Tell them: performance, goal, and meaning.
I find this kind of language, though, continues in software engineering because we lack better language to sufficiently describe what’s happening in our own heads—a mental model.
Having the approximately accurate mental model helps you explain to yourself what's going on. Once you have that then you can explain it to others and effectively help change it.
Potential models
So far I’ve been talking broadly about different kinds of mental models. I’ve been mostly treating them as one in this article, but I think there are at least 2 different groupings.
how do we’re doing the work
what we’re making
Let me give you several to help describe what I mean.
Mental models for how we’re doing the work:
Academia - getting to the answer
Artisan - making a high quality parts
Assembly Line - making the whole sequentially
Construction - making the whole in layers with different crews
Restaurant - different stations to assemble something
Mental models for what we're making:
Factory - a thing that makes other things
Infrastructure - a thing for someone to use indirectly
Residential building - an thing for someone to use directly
Supply chain - a thing to move other things
I do not mean to suggest that these are the only ones, nor do I mean to suggest that all of these models are correct. The point is to get started talking about what the right ways to think about this might be.
Knowledge work is increasing, not decreasing.
There’s an assumption that the recent AI resurgence will destroy white collar work. What it’s mostly doing is democratizing the ability for a single person to scale up their work in a way that has been historically reserved for software engineers.
So the sooner we start to have better language and understanding to discuss what exactly we’re doing, the better off we’ll be.
By the way, I started writing a book on the Laws of Software Engineering.
If that’s interesting to you, sign up to express interest in buying my book, and you’ll get status updates along the way.
COMMON SENSE FLUID MECHANICS, BENOIT CUSHMAN‐ROISIN Thayer School of Engineering Dartmouth College, Ch 15, https://cushman.host.dartmouth.edu/books/CommonSenseFM/Chap15.pdf
If you’re unlucky, they may even reflect what they've seen in TV and movies. Hence comments about the Matrix or “enhance” aren’t jokes, but things they thing you can literally do.