Skip to main content

Refactoring Cadence During Capstone: Boy-Scout + Occasional Deep

What This Concept Is

Refactoring cadence is the rhythm of structural change in the codebase, not its content. In a capstone with fixed delivery dates, two modes of refactoring matter:

  • Boy-scout refactoring -- many tiny cleanups made during ordinary feature work. "Leave the campsite cleaner than you found it." Rename this variable, extract this function, collapse this condition, delete this dead import. Each change is under 15 minutes. Fowler calls this opportunistic refactoring: the camp-site rule applied continuously.
  • Occasional deep refactoring -- short scheduled sessions (half a day to a day) aimed at a named problem: a duplicated concept, a tangled module, a layering violation. Driven by Fowler's Refactoring catalog of named moves (Extract Class, Replace Conditional with Polymorphism, etc.).

In a capstone, you need both. Boy-scout alone is too local to address the real structural rot that accumulates. Deep alone is too disruptive to do weekly and tempts you into yak-shaving.

The cadence is the thing being protected. Many capstones fail not because they lacked either mode but because the two modes were mixed -- every PR tried to be both a feature and a deep refactor, and neither landed cleanly.

Why It Matters Here (In the Capstone)

Two failure modes are common:

  • No refactoring. The code gets steadily uglier until a feature needs a day and a half of archaeology before any code can be written. Delivery stalls.
  • Too much refactoring. Every feature turns into a refactor tour. Delivery also stalls, because no feature ever ships.

The cadence defended here is:

  • every PR includes one or two boy-scout moves inside its normal diff;
  • every week has one scheduled 2-4 hour deep-refactor window aimed at a specific smell logged earlier;
  • no unscheduled refactor during a crunch sprint (ledger the smell and defer).

That rhythm keeps the codebase livable without letting refactoring eat delivery.

Concrete Example(s) -- from a real capstone

Week 4 of the capstone. The task-manager's TaskService is getting long.

Boy-scout during ordinary work (daily):

  • While fixing BUG-2026-04-04-01 in TaskService, rename fetchTaskById to get_task to match the rest of the repo.
  • Extract the 10-line validation block into validate_task_input.
  • Delete an unused import and one commented-out function.

Total time: 20 minutes across the day, rolled into the PR for the bug fix.

Deep refactor (scheduled, Wednesday afternoon, 3 hours):

  • Smell identified last week in the self-review (Concept 14): "TaskService has 11 methods, of which 6 are about tags, not tasks."
  • Named refactor from Fowler's catalog: Extract Class (tag handling moves to TagService).
  • Work plan: write characterization tests if missing, extract class, move methods, update call sites, run full suite, commit.

That deep refactor is scheduled, scoped, and closed on the same day. The codebase is smaller in coupling and the debt ledger loses one entry.

Common Confusion / Misconceptions

The biggest confusion is treating all refactoring as discretionary. Boy-scout refactoring is not discretionary; it is the default. Every PR should leave its touched code slightly cleaner. Deep refactoring is the part that needs a schedule.

The second confusion is starting deep refactors without naming the move. "Clean up the service" is not a plan. "Apply Extract Class to move tag handling out of TaskService" is. Fowler's refactoring catalog is the vocabulary; use its names.

The third is refactoring without tests. Boy-scout moves must have a safety net at the level of the change. Deep refactors must have characterization tests written first (Feathers). Refactoring without tests is rewriting, and rewriting in a capstone sprint is a delivery risk.

The fourth is conflating boy-scout cleanup with unscheduled drive-by renames across forty files. A large rename is a scheduled refactor with its own PR and its own tests, not a cleanup that rides along with a feature.

How To Use It (In Your Capstone)

Inside ordinary work (boy-scout):

  1. If the file you touched has a name that is wrong, a variable that is confusing, or dead code, fix it in the same PR.
  2. Do not exceed ~15 minutes of cleanup per PR. If it is larger, write a ledger entry and do it separately.
  3. Keep the diff explainable: a reviewer should see the boy-scout changes cleanly separated or obvious.
  4. If the cleanup changes behavior, it is not boy-scout -- split into refactor then feature.
  5. Run the full test suite after each cleanup, not just the tests you touched.

Weekly deep refactor:

  1. Pick one smell from your debt ledger (Concept 15) or self-review (Concept 14).
  2. Name the Fowler refactor that applies (Extract Class, Replace Temp with Query, Decompose Conditional, etc.).
  3. Confirm test coverage at the level of the change; add characterization tests if missing.
  4. Execute the refactor in a small number of mechanical steps. Run the suite between steps.
  5. Close the ledger entry that triggered the refactor and link the commit.
  6. If the refactor exceeds the 4-hour budget, revert and cut it smaller.
  7. Never mix a deep refactor with a feature in the same PR.

Boy-Scout Move Catalog (under 15 minutes each)

  • Rename a variable, parameter, or function whose name no longer fits
  • Extract function when a block of 10+ lines has a name
  • Inline function when the extracted function is a trivial rename that adds noise
  • Delete dead code: commented-out blocks, unused imports, unreferenced files
  • Collapse condition: if x: return True else: return False becomes return x
  • Replace magic number with constant with a domain-meaningful name
  • Move method to the class it actually belongs to (one move, not a reorganization)

Named Deep Refactors (Fowler catalog hits)

  • Extract Class -- one class has grown two distinct responsibilities.
  • Replace Conditional with Polymorphism -- a long if/elif dispatching on type.
  • Introduce Parameter Object -- 5+ arguments that always travel together.
  • Replace Temp with Query -- a local variable computed once becomes a method.
  • Decompose Conditional -- a 30-line if becomes a function call with a named predicate.

Each is 1-4 hours of focused work with tests. Do not mix two of these in one session.

Anti-Patterns to Recognize

  • Refactor-and-feature in one PR. Reviewer cannot separate intent from structure.
  • Untested deep refactor. Extract Class without characterization tests first.
  • Drive-by rename across files. A rename that touches 40 files in a capstone PR is rarely boy-scout.
  • Permanent "refactor branch." A branch where refactors accumulate and never merge.

See also (integrative)

External references:

Check Yourself

  1. What is the difference between boy-scout and deep refactoring, and how do you decide which mode fits a given smell?
  2. Why name deep refactors using Fowler's catalog rather than ad hoc descriptions?
  3. When is the right response to rot "do not refactor right now"?
  4. Why is a 40-file rename usually not boy-scout work?
  5. What is the role of characterization tests in a deep refactor, and what happens if you skip them?

Mini Drill or Application (Capstone-scoped)

  1. This week, log three boy-scout moves you made during normal work with one sentence each.
  2. Pick one smell in your code and name the Fowler refactor that applies. Schedule a 3-hour window.
  3. Before the session, write characterization tests at the level of the change and confirm they pass on the current code.
  4. Execute the refactor in small steps, running the full suite between each step; commit each step separately within the window.
  5. Close the corresponding debt-ledger entry with a commit link, and if the refactor affected module boundaries, open an ADR to record the decision.

Source Backbone

Capstone implementation applies earlier code-quality, testing, and refactoring material. These books are the source backbone for that practice.