Software design gets worse before it gets better

Software engineers reflect on Kent Beck’s idea that improving a codebase often requires passing through a “trough of despair,” where structure and productivity temporarily get worse before they improve. Commenters weigh incremental refactoring against full rewrites, noting issues like incomplete tests, legacy complexity, microservices sprawl, shifting business priorities, and incentives that discourage long-term cleanup. Many conclude that “better” software means designs that make future changes easier and safer, but stress that this only pays off if teams plan the transition carefully and are allowed to finish the journey out of the trough.

Rewrites vs Incremental Change

  • Strong debate over rewriting from scratch vs gradually transforming existing systems.
  • Some argue whole‑app rewrites are almost never justified; targeted refactors and partial replacements are different and often preferable.
  • Others note cases where years spent “bashing legacy into shape” feel like sunk‑cost fallacy, and a clean reimplementation (guided by tests) might have been better.
  • Several point out that test suites can be incomplete or encode unintended “bug‑as‑feature” behavior, limiting how far you can safely rewrite.

Microservices, Architecture, and Org Decisions

  • Microservices are seen as an infra/org choice that heavily constrains software design, often adopted prematurely as a “template” rather than a design.
  • Some argue infra/devops/org structure are themselves part of software design, especially in distributed systems.
  • Merging microservices or building new services “next to” legacy code is suggested as a practical middle ground.

The “Trough of Despair” and Redesign Risk

  • Many agree that moving from a local maximum to a better design requires a temporary dip: intermediate states are messier and more complex.
  • Others say the article conflates “less improvement than hoped” with “actually worse,” and that intermediate states are transitions, not designs.
  • Advice: prototype, draw current vs ideal vs feasible architectures, and build “stairs” before fully descending into the trough.
  • A frequent failure mode: orgs fund the “make it worse” step but never the “make it better” step.

What Counts as “Better”?

  • For developers: easier to change, clearer architecture, lower marginal cost for future features, less technical debt.
  • For users: simpler, more predictable tools that support goals with minimal friction.
  • Tension noted between developer convenience (e.g., cross‑platform stacks, Electron) and user experience (native, “Mac‑like” apps).
  • Some emphasize measurable qualities (maintainability, reliability, performance, security) over aesthetic purity.

People, Incentives, and Skill

  • Frequent job‑hopping and weak career paths make long‑term refactoring less appealing; companies often under‑reward those who stay.
  • Outsourcing and “cheap labor” are blamed for poor design that later must be redone by smaller, more skilled teams.
  • Others note high salaries do not guarantee high skill; tooling and abstraction can mask incompetence.

Metaphors: Local Maxima, Activation Energy, Evolution

  • Commenters liken redesign to leaving a local optimum, chemical activation energy, and simulated annealing.
  • Debate over whether real‑world evolution is monotonic; consensus that non‑monotonic change (taking short‑term “worse” steps) is often necessary to escape design traps.