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, renamefetchTaskByIdtoget_taskto 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): "
TaskServicehas 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):
- 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.
- Do not exceed ~15 minutes of cleanup per PR. If it is larger, write a ledger entry and do it separately.
- Keep the diff explainable: a reviewer should see the boy-scout changes cleanly separated or obvious.
- If the cleanup changes behavior, it is not boy-scout -- split into refactor then feature.
- Run the full test suite after each cleanup, not just the tests you touched.
Weekly deep refactor:
- Pick one smell from your debt ledger (Concept 15) or self-review (Concept 14).
- Name the Fowler refactor that applies (Extract Class, Replace Temp with Query, Decompose Conditional, etc.).
- Confirm test coverage at the level of the change; add characterization tests if missing.
- Execute the refactor in a small number of mechanical steps. Run the suite between steps.
- Close the ledger entry that triggered the refactor and link the commit.
- If the refactor exceeds the 4-hour budget, revert and cut it smaller.
- 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 Falsebecomesreturn 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/elifdispatching 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
ifbecomes 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)
- S3 M02 Refactoring Techniques -- the move vocabulary and mechanics
- S3 M01 OOD Foundations & Smells -- the smell catalog that triggers a deep refactor entry
- S3 M05 Applied Design & Code Review -- self-review as the source of refactor candidates
- S7 M02 Architecture Patterns & Modular Design -- when a deep refactor is really a module-boundary decision
- S7 M05 ADRs & Reviews -- recording a deep refactor's rationale as an ADR when it affects architecture
External references:
- Martin Fowler: Opportunistic Refactoring -- the camp-site rule in practice
- Fowler: Refactoring Catalog -- named moves and their mechanics
- Understand Legacy Code: Working Effectively with Legacy Code key points -- Feathers on characterization tests as a pre-refactor safety net
- DaedTech: Characterization Tests -- pattern for pinning current behavior before refactoring
- The Boy Scout Rule (Matias Frndz summary) -- Uncle Bob's framing
Check Yourself
- What is the difference between boy-scout and deep refactoring, and how do you decide which mode fits a given smell?
- Why name deep refactors using Fowler's catalog rather than ad hoc descriptions?
- When is the right response to rot "do not refactor right now"?
- Why is a 40-file rename usually not boy-scout work?
- What is the role of characterization tests in a deep refactor, and what happens if you skip them?
Mini Drill or Application (Capstone-scoped)
- This week, log three boy-scout moves you made during normal work with one sentence each.
- Pick one smell in your code and name the Fowler refactor that applies. Schedule a 3-hour window.
- Before the session, write characterization tests at the level of the change and confirm they pass on the current code.
- Execute the refactor in small steps, running the full suite between each step; commit each step separately within the window.
- 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.
- Software Engineering at Google - testing, review, and engineering-process backbone.
- Refactoring - safe change and behavior-preserving improvement.
- Good Code, Bad Code - maintainability and code-quality judgment.
- Clean Code - readability and function-level craft support.