Skip to content
Part IA Easter Term

Refactoring, Code Smells, and the Strangler Fig Pattern

Refactoring

Refactoring is the disciplined restructuring of existing code without changing its observable behaviour. It is not “cleaning up” in a vague sense — it is a precise engineering technique with a clear invariant: tests pass before, tests pass after.

Prerequisite: a comprehensive automated test suite. Without tests, refactoring is indistinguishable from breaking changes — you have no way to verify that behaviour was actually preserved.

Code Smells

A code smell is not a bug. It is a signal that the design is decaying — a pattern that often (though not always) indicates a deeper structural problem. Smells are heuristics, not rules; they invite investigation, not automatic refactoring.

SmellDescriptionWhy it matters
Long MethodA function that does too many things. If you cannot describe what it does in one sentence, it is too long.Hard to test in isolation; hard to understand; hard to reuse parts of it
God ObjectA class that knows too much or does too much — violating the Single Responsibility PrincipleA change to any behaviour requires modifying this class; merge conflicts concentrate on this file
Feature EnvyA method that accesses another class’s data far more than its own — it “envies” the other classSuggests the method belongs on the other class; indicates misplaced responsibility
Data ClumpsGroups of variables that are always passed together (e.g. x, y, z coordinates; startDate, endDate)Suggests a missing abstraction — a Point class or a DateRange object
Switch StatementsRepeated switch/if-else chains on type codesSuggests polymorphism should replace conditional logic — add a new type and you must find and update every switch statement

Characterisation (Golden Master) Tests

How do you refactor code that has no tests and no understood requirements? You cannot assert correctness (you do not know what “correct” means). Instead, you assert consistency:

  1. Feed the function a diverse set of real inputs.
  2. Record the exact output it currently produces for each input.
  3. This recording is the “Golden Master.”
  4. After refactoring, run the same inputs and assert the output is byte-for-byte identical.

You are not testing that the code is correct — just that your restructuring did not change anything. This is a critical technique in the legacy-code toolbox.

The Strangler Fig Pattern

Strangler Fig pattern: a proxy/facade sits in front of the legacy system. New functionality is built as a separate service. Traffic is incrementally routed from legacy to new until legacy receives zero traffic and can be decommissioned.

Named after the vine that grows around a tree, eventually replacing it entirely. In software, the Strangler Fig pattern is a low-risk, incremental approach to replacing a legacy system:

  1. Place a Proxy / Facade in front of the legacy system. All incoming requests go through the facade; the facade decides whether to route to the legacy system or to the new service.
  2. Build new functionality as a separate service alongside the legacy system — not touching the legacy code at all.
  3. Route specific calls to the new service. Start with the least risky, most isolated feature. The rest of the traffic continues to hit legacy.
  4. Incrementally migrate more and more functionality to the new service.
  5. When the legacy system receives zero traffic — decommission it.

Benefit: low risk. At every point, the legacy system is still running and can handle any traffic not yet migrated. Features continue to ship during the migration (unlike a Big Bang rewrite). If the new service has a problem, the facade routes back to legacy.

The Big Bang Rewrite: Netscape’s Disaster (1997)

Netscape Navigator dominated the browser market in the mid-1990s — but its codebase was “messy.” In 1997, Netscape threw away Navigator’s codebase entirely and began a complete, from-scratch rewrite: Netscape Communicator 5.0.

The rewrite took 3 years with zero new features shipped to users during that entire period. Meanwhile, Microsoft Internet Explorer — shipping new features continuously — captured 90% of the browser market. Netscape went bankrupt; the company was eventually acquired by AOL.

The rule: never do a Big Bang rewrite of a successful system. It is high-risk because:

  • All feature delivery halts for an extended, uncertain period.
  • Competitors continue shipping and capturing market share.
  • The new system is built from a fresh, incomplete understanding of the old one — silently dropping features and behaviours that real users depend on (Hyrum’s Law).
  • The “all-or-nothing” cutover concentrates all migration risk into a single high-stakes event — if the new system has a critical bug on launch day, there is no fallback.

The Y2K Bug: Technical Debt at Global Scale

In the 1960s–1980s, memory was expensive. To save two bytes per date, years were stored as two digits: 98 instead of 1998. The assumption: “this code will be replaced long before the year 2000.”

The reality (Lehman’s Law of Continuing Change): those systems stayed in use for 30–40 years. The “temporary” shortcut accruing interest for decades. In 1999, the world spent an estimated $300 billion to inspect and patch embedded systems, financial mainframes, and infrastructure control software to prevent global collapse when 00 rolled around.

Lesson: short-term technical debt can carry multi-billion-pound long-term interest. The debt you take on today may outlive your career — and someone else will have to pay the interest.

Expected Learning

  • Define refactoring and explain why an automated test suite is its prerequisite.
  • Name at least three code smells and describe why each indicates structural decay.
  • Explain what characterisation tests are and when they are used.
  • Describe the Strangler Fig pattern in four steps, and explain why it is lower-risk than a Big Bang rewrite.
  • Explain Netscape’s Big Bang rewrite failure as a case study in migration risk.
  • Describe the Y2K bug as an example of technical debt compounding over decades.

Past Paper Questions

Example Sheet 2, Question 7(a-c) tests the Big Bang rewrite risks (the Netscape case study) and asks you to describe the Strangler Fig approach for migrating a legacy COBOL system — including how Hyrum’s Law complicates the migration because undocumented behaviour is relied upon by downstream consumers.