Iron Crosses in Software Engineering

Iron crosses describe the trade-off space of a solution to a problem, and occur due to competing demands on resources. The classic one is for project management: good, fast, cheap, done. It is often assumed that ‘done’ is non-negotiable, so that trade space just ‘good, fast, cheap; pick two’.

In software engineering, an important trade space is between simplicity, generality, efficiency, and punctuality; or more casually; simple, general, efficient, done.

Simple solutions are cheap (in terms of effort) to maintain, cheap to change, cheap to onboard new maintainers, and easy to hand over.
The fundamental constraint is information/understanding/context and how much is required to understand the solution.

General solutions solve a wider variety of problems, including the one in question, such that you only need one solution for a wide class of problems. Maintenance cost is be amortized over many projects, and duplication of effort is minimize.
The fundamental constraint is scope/abstraction and how many different features are expanded when implementing the solution.

Efficient solutions are cheaper (in terms of dollar cost, or energy) to deploy, more responsive and have lower hardware requirements.
The fundamental constraint here is hardware affinity and how tightly coupled the solution is to the particular set of hardware.

Punctual solutions are done on time and under budget.
The fundamental constraint here is resources; how many (and with experience) are allocated to the solution.

You want them all, but can only choose three.

These are competing constraints, so deliberate or otherwise, a choice is always made.
Better tools make the return on investment cheaper, but can’t make those tradeoffs disappear.

Both engineers and product managers have (usually implicit) assumptions/preferences about how these trade offs are to be made for a given problem. Preferences vary depending on background, culture and tech. Application / library developers tend to like general & efficient, systems programmers tend towards simple & efficient, web development towards towards simple & general. Product managers generally want simple and done.

Failures occur when stakeholder trade-off expectations don’t align.

Example: developer wants to implement a general and efficient solution since they’ll expect to need it later for a different project. Product manager wants it done quickly and simply due to timeline and resource pressure.

Possible outcome: Developer sees PM as making future pain, impacting morale and causing frustration. Product manager see developer as not aligned with business goals and having the wrong priorities. Thing gets shipped but nobody is happy about it.

Usual outcome; developer delivers it late, it’s over-complicated and hard to maintain. It’s also buggy and needs performance issues fixed before it’s usable. If it gets shipped, it gets shipped late and nobody is happy about it.

It is crucial to find alignment between stakeholders in order to reach a mutually satisfactory solution.