Software Evolution & Design Pathologies¶
← Back to Domain-Specific Families
Abstractions about software change, maintainability, design defects, and recurring development failures. They include code smells and anti-patterns, interface segregation, legacy migration, behavior-driven development, complexity and entropy, estimation failure, and Lehman’s laws of software evolution.
23 abstractions in this family — domain-specific abstractions that sit near one another in structural-signature space (k-means over structural-signature embeddings). Each is shown with its short description.
- Behavior-Driven Development — Develop software through collaborative discovery of concrete behavior examples that become shared, automatable specifications linking business intent to observable system outcomes.
- Code Smell — Treat an observable feature of code as defeasible evidence of a deeper design or maintainability problem—not proof of a defect—so inspection triggers a context test and a refactoring hypothesis.
- Comments as Deodorant — Read the need for an explanatory comment as a diagnostic signal, not a virtue — a clear paragraph explaining a confusing function masks a retirable design problem instead of fixing it, so do the rename or split that retires the comment rather than maintaining it.
- Dialectics — Contradictions drive change.
- God Object Anti-Pattern — Diagnose a maintenance mess as concentrated rather than diffuse: one class or service accumulates outlier fan-in and fan-out to become the integration hub, collapsing modularity so all change-cost, comprehension, and new features funnel through that single node.
- Greenspun's Tenth Rule — The aphorism that any sufficiently complicated C or Fortran program contains an ad hoc, bug-ridden implementation of half of Common Lisp — because features a language withholds do not vanish but migrate inside the program as defective re-implementations.
- HAZOP Guideword Miss — The structural failure in which a HAZOP's finite guideword-times-parameter-times-node grid never generates the deviation that later causes an incident, because the hazard fell outside the schema's coverage boundary and was never identified, safeguarded, or risk-assessed.
- Interface segregation principle — The SOLID rule that clients should not depend on interface methods they do not use — decompose a fat interface into role-specific ones sized to each consumer's usage footprint, so a contract change's blast radius is read off the boundary rather than the call graph.
- Lava Flow (Anti-Pattern) — Explain why obsolete or unused code hardens into a codebase when uncertain dependencies and inadequate verification make deletion seem riskier than indefinite retention.
- Lazy Class — The code smell in which a class (or function, module, package) carries too little responsibility to justify the overhead it imposes — the defect living in the economy, not the behaviour, so a correct, clearly-named boundary can still be flagged when its carried value fails to clear its enumerable tax.
- Lehman's law of conservation of familiarity — Hold the mean change shipped per release of a long-lived software system roughly constant, because the producer and consumer communities have a bounded capacity to absorb novelty, and overdrawing it forces a corrective contraction.
- Lehman's law of conservation of organizational stability — Observe that a long-lived software organization's long-run work rate returns to a band set by structural parameters no matter how you push the local dials — staffing, hours, pressure — so durable throughput gains require restructuring, not loading.
- Lehman's law of continuing change — The empirical software-evolution law that an E-type system — one embedded in a moving real-world environment — must be continually adapted or it progressively becomes less satisfactory, because its fitness is relational (the gap between what the code does and what the world now requires) and that gap widens monotonically while the code stands still.
- Lehman's law of continuing growth — State that a long-lived software system must continually expand its functional content to retain users, because satisfaction is judged against a rising competitive reference point — adaptation alone holds fitness constant while rivals grow past it.
- Lehman's law of declining quality — Read software quality as the system's fit to its present environment rather than its intrinsic defect count, so an unchanged, bug-free release still degrades in the field as the surrounding world drifts away from the conditions it was built for.
- Lehman's law of increasing complexity — Observe that the structural, behavioral, and conceptual complexity of an evolving software system rises monotonically under unmanaged change — an entropy-positive default that only deliberate, non-feature restructuring can bend back down.
- Lehman's law of self regulation — Treat a long-lived software project as a closed feedback loop that self-regulates around an operating point, so single-node pushes are absorbed and only structural changes to the loop durably relocate its release-size, cadence, and defect-density distributions.
- Line of Effort — Structure a campaign around a condition to be created rather than terrain by laying out parallel rails of task → effect → effect → end state, each an auditable causal chain coupled to the others only at named handoff points.
- Means-End Analysis — A greedy problem-solving heuristic that repeatedly finds the most significant difference between the current and goal states, applies the operator that most reduces it, and recurses on any unmet preconditions as sub-goals.
- Ninety-Ninety Rule — The first 90 percent of the code takes the first 90 percent of the time and the last 10 percent takes the other 90 percent — a deadpan warning that nominal-progress metrics measure only the estimable bulk-work population and never the non-parallelizable, heavy-tailed completion tail.
- No Silver Bullet — Brooks's thesis that no single innovation will yield an order-of-magnitude gain in software productivity within a decade, because past gains already mined the accidental complexity (tool-and-environment friction) and the binding constraint is now essential complexity — difficulty inherent in the problem that no tool can dissolve.
- Software Entropy — Read a codebase's growing structural disorder as a predictable gradient under continuous modification: locally expedient edits flow toward the vast basin of working-but-disordered states, and order decays monotonically unless restoring engineering effort is continuously reinjected.
- Strangler Fig Pattern — Replace a legacy system incrementally in place by fronting it with a stable interception layer, rerouting one validated request path at a time to the replacement, and retiring the legacy once nothing routes to it.