Skip to content

Lab 2.4: Incremental Improvement

Module: 2.4 - Safe Refactoring | ← SlidesDuration: 1 hour Sample Project: node-express-mongoose-demo

Learning Objectives

By the end of this lab, you will be able to:

  • Refactor code safely with test verification
  • Make incremental changes (small steps)
  • Improve readability without changing behavior
  • Use tests as a safety net

Prerequisites

  • Completed Labs 2.2 and 2.3
  • Tests in place for the code you'll refactor
  • Confidence in running the test suite

The Safe Refactoring Workflow

1. Verify tests pass (baseline)
2. Make one small change
3. Run tests
4. If green: commit and continue
5. If red: revert and try again

Setup

bash
# Navigate to the sample project
cd sample-projects/node-express-mongoose-demo

# Verify tests pass BEFORE starting
npm test

# Start Claude Code
claude

Task 1: Identify Code Smells

Time: 10 minutes

Find code that needs improvement.

Prompts to try:

What code smells exist in app/controllers/articles.js?
Are there any functions with too many responsibilities?
Find examples of duplicated code in this project.

Common code smells:

  • Long methods (>20 lines)
  • Duplicated code
  • Poor naming
  • Deep nesting
  • Magic numbers/strings

Success criteria:

  • [ ] Identified 2-3 code smells
  • [ ] Selected one to fix

Task 2: Refactor for Readability

Time: 15 minutes

Improve variable and function names.

Step 1: Run tests (baseline)

bash
npm test

Step 2: Improve naming

Rename the variables in this function to be more descriptive. Don't change any behavior.
The function name 'proc' is unclear. Suggest a better name and rename it throughout the codebase.

Step 3: Verify tests pass

bash
npm test

Success criteria:

  • [ ] Names are clearer
  • [ ] Tests still pass
  • [ ] Behavior unchanged

Task 3: Extract Helper Functions

Time: 20 minutes

Break down complex functions.

Step 1: Identify extraction opportunities

This function is too long. What parts could be extracted into separate functions?

Step 2: Extract one piece

Extract the [specific logic] into a separate helper function.

Step 3: Run tests

bash
npm test

Step 4: Repeat for other pieces

Success criteria:

  • [ ] At least one function extracted
  • [ ] Tests pass after each extraction
  • [ ] Main function is now shorter

Task 4: Remove Duplication

Time: 15 minutes

DRY up the codebase.

Step 1: Find duplication

Find duplicated code between the create and update functions.

Step 2: Extract shared logic

Extract the common validation logic into a shared function used by both create and update.

Step 3: Verify

bash
npm test

Success criteria:

  • [ ] Duplication removed
  • [ ] Shared function created
  • [ ] Tests pass

Refactoring Techniques

TechniqueWhen to UseExample
RenameUnclear namesxuserId
Extract FunctionLong methodsPull out 10 lines into helper
InlineOver-abstractionRemove unnecessary wrapper
MoveWrong locationMove util from controller to utils/
Replace MagicHard-coded values86400SECONDS_PER_DAY

The Golden Rule

Remember

"Refactoring is changing code without changing behavior."

After every change:

  1. Run tests
  2. If they pass, you're safe
  3. If they fail, you changed behavior (revert!)

Commit Strategy

Commit after each successful refactoring:

bash
# After each green test run
git add .
git commit -m "Refactor: Extract validation helper from article controller"

Small commits = easy rollback if something goes wrong.


Tips for Success

  1. One change at a time - Don't combine refactorings
  2. Run tests constantly - After every single change
  3. Commit frequently - Save your progress
  4. Keep behavior identical - If tests fail, you went too far

Common Refactoring Prompts

Rename this variable to something more descriptive.
Extract the loop body into a separate function.
Replace this magic number with a named constant.
Simplify this nested if-else into an early return pattern.

Red Flags (Stop Refactoring)

  • Tests start failing unexpectedly
  • You're adding new features (that's not refactoring)
  • Changes are getting too large to track
  • You've been refactoring for >30 min without committing

Stretch Goals

If you finish early:

  1. Refactor deeply nested conditionals into guard clauses
  2. Extract a configuration object from scattered magic values
  3. Improve error handling consistency

Deliverables

At the end of this lab, you should have:

  1. Cleaner, more readable code
  2. Smaller, focused functions
  3. Reduced duplication
  4. All tests still passing
  5. Clean commit history showing incremental changes

Next Steps

After completing this lab, move on to Lab 2.7: Modernization Mini-Project - the Day 2 capstone.

Claude for Coders Training Course