Three Laws of Software Complexity
Feasibility of Rewrites vs Legacy Constraints
- Many see “just rebuild before it gets bad” as unrealistic for 15+ year legacy systems with huge sunk cost and active customers.
- Full rewrites are acknowledged to happen, but seen as rare, risky, and hard to justify as a general practice, especially when hidden complexity has accumulated (e.g., vast unknown SQL stored procedure forests).
- Incremental splitting into domains/“silos” and strangler patterns are viewed as more realistic, though still costly and risky.
Customer Value vs Engineering Quality
- One camp argues customers mainly care about features and revenue, not code cleanliness; complexity and tech debt are “our problem.”
- Others counter that poor internal quality leaks out as slow, buggy, awkward products, bad docs, and painful upgrades—customers do care, even if indirectly.
- Some note vendor selection is shaped by politics and imperfect information, not pure quality.
Refactoring, Tech Debt, and Investment
- Persistent refactoring is framed as a high-cost, diffuse-benefit investment that’s hard or impossible to quantify.
- Some engineers “just do it” without asking permission, folding refactors into feature work.
- Debate over how much to refactor when system lifetime is unpredictable; it’s likened to investment risk.
Entropy, Complexity, and Inevitability
- Many like the entropy analogy: disorder (bad design) is a more “stable” attractor without ongoing effort.
- Others stress that complexity growth is not a law but a strong tendency, driven by expedient decisions and lack of large, timely refactors.
Essential vs Accidental Complexity
- Several distinguish domain-inherent (“essential”) complexity from self-inflicted (“accidental”) complexity.
- Focusing on the true problem, independent of tech stack, is seen as a key skill; failure to do so inflates accidental complexity.
Culture, Incentives, and Capitalism
- Some say the “laws” mostly reflect bad or “regular” engineering culture and short-term business incentives.
- Others argue even good teams must spend continuous energy to fight complexity, and most orgs lack measurable incentive to do so.
- Long-lived, actively refactored systems (e.g., certain monoliths, Linux kernel) are cited as counterexamples to inevitability.
Metaphors and Attitudes
- Gardening, forest fires, and Sudoku are used as metaphors for continuous pruning, local fixes, and incremental improvement.
- Several see maintaining old systems as a legitimate, even enjoyable craft rather than a failure.