Good refactoring vs. bad refactoring

What Counts as Refactoring

  • Several commenters insist refactoring is, by definition, a structural change with no behavioral change; if behavior changes, it’s just “a change” or a feature/fix.
  • Others use a looser definition that allows behavior changes when simplifying design and think the strict definition is impractical in everyday speech.
  • One middle position: refactoring must preserve external behavior; internal behavior (e.g., removing implicit caching) can change if the contract stays the same.

Functional vs Imperative Styles

  • Strong split on readability: some find filter/map chains more expressive and closer to how they conceptualize data transformations; others understand loops instantly and see FP chains as harder to debug.
  • Readability is widely acknowledged as reader-dependent and largely a function of familiarity, not inherent superiority.
  • Performance concerns: FP chains can allocate more and traverse arrays multiple times; some have had to revert FP code to loops for speed. Others call this micro‑optimization unless profiling proves relevance.
  • Debugging FP and heavy abstraction is cited as harder, especially with lazy evaluation; imperative code and simple loops are seen as easier to step through.

Object-Oriented Refactor Example

  • Many argue the “OO refactor” in the article is not real OO, just a function wrapped in a class (named by verb/-or, doing work, not modeling a domain object).
  • Alternative OO approach suggested: put isAdult/formatted behavior on User (or related domain objects) and keep data + behavior together.
  • A long tangent debates whether “adult” is a property of the person, the jurisdiction, or their combination, illustrating how OO design can easily overcomplicate simple logic.

Consistency, Patterns, and Scope

  • Some endorse “if you introduce a new pattern, consider applying it everywhere” to avoid long-lived inconsistency and confusing archeological layers.
  • Others argue whole‑codebase rewrites are often infeasible; new patterns should be introduced incrementally, starting with new features and refactoring old code opportunistically.
  • “Pattern” is discussed broadly, not just in the Gang of Four sense; inconsistency is seen as technical debt but sometimes a necessary trade-off while experimenting.

When and Why to Refactor

  • Many say refactoring should almost always be in service of a concrete goal (feature, bugfix, performance, testability), not as a standalone beautification project.
  • Several teams reportedly bar new hires from large refactors for a few months to avoid “I don’t like this style” churn before they understand context.
  • Others push back, noting poor cultures misuse “no refactor” dogma to block necessary cleanup and that refactoring can help newcomers learn the code.

Code Size, Complexity, and Metrics

  • One view: good refactors should reduce code size (e.g., gzipped LOC) and complexity; less code tends to mean fewer bugs.
  • Counterview: size reduction is only a rough proxy; some beneficial refactors increase code volume (e.g., splitting classes, adding explicit types) but greatly improve comprehensibility and testability.

Critique of the Article and Tool Promotion

  • Multiple commenters find the article shallow or confused: examples often change behavior, conflate refactoring with redesign, or attack FP while using FP-like constructs elsewhere.
  • Some think it overemphasizes “inconsistency” and underexplains how to refactor safely.
  • Several note or suspect it functions largely as marketing for an AI refactoring tool, which reduces trust in its technical depth.