As I've evolved from being an individual software developer to managing teams and starting a company—a data science platform—I continue to notice parallels between the principles of good engineering and the principles of good management. I have no delusions of novelty here but it's an interesting topic with a lot of surface area, so I plan to write more about this over the coming months. For now, I want to focus on one specific similarity: situations where "someone" is unable to do what has been asked of them.
First, let me briefly acknowledge a foundational similarity between software and companies: good organizational design "looks like" good software design. That is, "units" should have clear responsibilities and clear "contracts" (or interfaces) for how they connect with other units. On its own, this isn't particularly insightful but with that in mind, let's dig a bit deeper...
Exceptions and Escalations
A more subtle similarity is the idea of an Exception in software development, and its analog in a management context.
My previous employer had a formal notion of an Escalation (documented in the firm's publicly available management handbook). There were a few different scenarios where one might "escalate" something, but the most common was when you were "unable to achieve your responsibilities."
This sounds obvious at first glance, but it's a subtle and powerful concept. This idea applies to everyone in an organization — no matter how junior or senior — and it requires that they have the self-awareness and egoless-ness to recognize if/when they are unable to fulfill their responsibilities, regardless of the reason. That could include a janitor who can't clean an office because he's missing a key; an engineering manager who is unable to deliver a release on time because her business stakeholders aren't providing enough feedback on early versions; or a senior manager who is unable to get a department on track because he recognizes he doesn't have the experience or conceptual ability to solve the scale of problems he is facing. All of these situations would warrant an Escalation.
In software engineering, an Exception is essentially the same thing: a unit of code should raise an Exception when it is unable to fulfill its responsibility. (Microsoft's .NET Framework Guidelines actually use very similar language: "Exceptions are thrown when a member cannot successfully do what it is designed to do".)
Completing the analogy
We can integrate this parallel between exceptions and escalations into the more obvious parallel we first observed:
- Organizational units
Well-designed companies have departments and teams with clear responsibilities.
Well-designed software has modules and classes with clear responsibilities
Individuals who do things
In a company, departments and teams have a single manager, who reports to a "higher up" manager, and who is responsible for making use of her own reports to achieve the responsibility of the department or team.
In software, a function is invoked by some other function and has other functions available that it can call to deliver the promise of its signature.
Exceptions and Escalations
In a company, if a person cannot do what has been asked of her, she should raise an Escalation to this effect, letting her manager handle this fact appropriately.
In software, if a function cannot do what it was asked to do, it should raise an Exception, letting the calling function handle this factor appropriately.
Note that in the same way that a function is responsible for handling Exceptions from any other functions it calls, a manager is responsible for handling Escalations from her reports. "Handling" an Exception or an Escalation could entail resolving the underlying issue and "re-trying"; it could entail achieving the same responsibility through some different means (e.g., calling a different function, giving the task to a different person or group); or it could involve passing the Exception/Escalation up to the next layer (i.e., the previous function on the stack, or the next manager up the chain).
Here's an example of a simplified org structure and a simplified software architecture, showing some examples of possible exceptions and escalations. The red arrow represents "someone" (a person or a function) saying, "I am unable to do what was asked of me."
In the same way that learning a foreign language can nurture a deeper understanding of your native language, I have found that seeing this same concept in two different domains has helped me appreciate it more in each of them.
In a software development context, this reflection has led to stark clarity about when it's appropriate to throw an Exception: if and only if the function cannot uphold the promise of its signature.
In a management context, it has become more clear to me that for an Escalation scheme to work, everyone in the organization must understand it and operate according to the protocol. If an Escalation is raised, but managers don't know how to "handle" them, the system fails. Or if people don't know they should Escalate when unable to achieve their responsibilities, the system fails. (The analogy to writing good code should be self-evident, here.)