Refactoring từng phần
Module 9.2: Refactoring từng phần
Phần tiêu đề “Module 9.2: Refactoring từng phần”Thời gian học: ~35 phút
Yêu cầu trước: Module 9.1 (Khai quật code cũ)
Kết quả: Sau module này, bạn sẽ có systematic approach refactor legacy code incremental, biết guide Claude toward safe change, và hiểu refactor-test-commit workflow.
1. WHY — Tại Sao Cần Hiểu
Phần tiêu đề “1. WHY — Tại Sao Cần Hiểu”Đã hiểu legacy code (Module 9.1). Time to improve. Bạn bảo Claude “refactor 500-line function này.” Claude produce beautiful rewrite — break 3 integration bạn không biết tồn tại. 2 ngày debug, cuối cùng revert hết.
Big refactor risky. Incremental refactoring là cách professional improve legacy code: small step, mỗi bước verify, always rollback-ready. Claude help được — nhưng cần guide toward incrementalism.
Như sửa nhà đang ở — không đập tường rồi mới xây. Dọn từng phòng, sửa từng phần, mỗi bước vẫn ở được.
2. CONCEPT — Ý Tưởng Cốt Lõi
Phần tiêu đề “2. CONCEPT — Ý Tưởng Cốt Lõi”Incremental Principle
Phần tiêu đề “Incremental Principle”- One change at a time
- Verify sau mỗi change
- Commit sau mỗi verified change
- Rollback phải trivial
Refactoring Loop
Phần tiêu đề “Refactoring Loop”graph LR A[Identify Smell] --> B[Plan Small Change] B --> C[Implement] C --> D[Verify] D --> E[Commit] E --> F{More Smell?} F -->|Yes| A F -->|No| G[Done]Safe Refactoring Pattern
Phần tiêu đề “Safe Refactoring Pattern”| Pattern | Risk Level | Example |
|---|---|---|
| Rename variable/function | Very Low | data → userData |
| Extract method | Low | Pull 10 dòng vào function mới |
| Extract class | Medium | Move related method sang class mới |
| Change signature | Medium | Add/remove parameter |
| Restructure logic | High | Change conditional, loop |
| Change data structure | Very High | Array → Map, sync → async |
Guide Claude Toward Incrementalism
Phần tiêu đề “Guide Claude Toward Incrementalism”Key prompt:
- “Suggest SMALLEST refactoring improve code này.”
- “What’s ONE thing rename để improve readability?”
- “Extract ONLY validation logic vào separate function.”
- “DO NOT change public interface. Internal only.”
- “Existing test MUST still pass.”
Strangler Fig Pattern
Phần tiêu đề “Strangler Fig Pattern”Không rewrite old code — wrap nó:
- Create wrapper call old function
- New code call wrapper
- Gradually move logic từ old sang wrapper
- Eventually old code empty → remove
Ask Claude: “Create wrapper cho [old function] để gradually migrate.”
3. DEMO — Từng Bước
Phần tiêu đề “3. DEMO — Từng Bước”Scenario: Legacy function saveUserData() — 200 dòng, làm validation, processing, VÀ saving. Cần break apart.
Step 1: Identify Smell
Phần tiêu đề “Step 1: Identify Smell”Bạn: Read saveUserData() trong userService.js.Code smell nào thấy? List theo độ dễ fix.
Claude:1. Function làm 3 việc (validate, process, save) — extract method2. Magic number (line 45: if (age > 18)) — extract constant3. Deep nesting (4 level if) — flatten conditional4. Unclear variable name (d, x, temp) — rename
Dễ đến khó: Rename → Constant → Extract method → FlattenStep 2: Plan Smallest Change
Phần tiêu đề “Step 2: Plan Smallest Change”Bạn: Start với dễ nhất. Suggest ONLY variable renameimprove readability. Không change logic.
Claude:- Line 12: d → userData- Line 34: x → validationResult- Line 56: temp → processedDataStep 3: Implement với Verification
Phần tiêu đề “Step 3: Implement với Verification”Bạn: Make only 3 rename đó. Nothing else.
Claude: [Rename đúng 3 variable]$ npm testOutput:
PASS src/services/userService.test.jsAll tests passed ✓Step 4: Commit Increment
Phần tiêu đề “Step 4: Commit Increment”$ git add userService.js$ git commit -m "refactor: rename unclear variables in saveUserData"Step 5: Next Increment
Phần tiêu đề “Step 5: Next Increment”Bạn: Good. Next: extract validation logic (line 20-50) vàoseparate function validateUserData(). Keep same behavior.
Claude: [Extract validation vào function mới]$ npm testOutput:
PASS src/services/userService.test.jsAll tests passed ✓$ git commit -am "refactor: extract validateUserData from saveUserData"Step 6: Continue Until Clean
Phần tiêu đề “Step 6: Continue Until Clean”- Increment 3: Extract
processUserData() - Increment 4: Extract constant
- Increment 5: Flatten conditional
Mỗi cái: implement → test → commit
Result: 200-line function → 4 clean function + constant. 5 commit. Mỗi commit là safe rollback point. Zero breakage.
4. PRACTICE — Tự Thực Hành
Phần tiêu đề “4. PRACTICE — Tự Thực Hành”Bài 1: Rename Game
Phần tiêu đề “Bài 1: Rename Game”Goal: Practice lowest-risk refactoring.
Instructions:
- Tìm file với unclear variable name
- Ask Claude suggest ONLY rename (no logic change)
- Implement, test, commit
- Repeat until naming clean
💡 Hint
"List all variable name trong function này có thể clearer.Suggest better name. Do NOT change logic."Bài 2: Extract Method Drill
Phần tiêu đề “Bài 2: Extract Method Drill”Goal: Practice incremental extraction.
Instructions:
- Tìm long function (50+ dòng)
- Ask Claude: “ONE section nào extract được vào helper function?”
- Extract chỉ section đó
- Test, commit
- Repeat 3 lần
Bài 3: Strangler Fig Practice
Phần tiêu đề “Bài 3: Strangler Fig Practice”Goal: Learn wrap-and-migrate pattern.
Instructions:
- Pick legacy function muốn replace
- Ask Claude create wrapper call old function
- Move ONE piece logic từ old sang wrapper
- Test, commit
- Repeat until old function empty
✅ Solution
Step 1: "Create wrapper function newProcessOrder()simply call old processOrder() và return result."
Step 2: "Move ONLY validation logic từ processOrder()vào newProcessOrder(). Keep everything else call old function."
Step 3: Repeat cho mỗi piece logic until old function empty.5. CHEAT SHEET
Phần tiêu đề “5. CHEAT SHEET”Incremental Refactoring Loop
Phần tiêu đề “Incremental Refactoring Loop”- Identify smell
- Plan smallest fix
- Implement
- Test
- Commit
- Repeat
Safe Refactoring Prompt
Phần tiêu đề “Safe Refactoring Prompt”"What's SMALLEST change improve this?""Suggest ONLY rename, no logic change.""Extract ONLY [specific section] vào new function.""DO NOT change public interface.""Existing test MUST still pass."Risk Level
Phần tiêu đề “Risk Level”- Very Low: Rename, reformat
- Low: Extract method, add comment
- Medium: Extract class, change signature
- High: Restructure logic
- Very High: Change data structure
Git Rhythm
Phần tiêu đề “Git Rhythm”# After each increment:npm test && git commit -am "refactor: [what you did]"6. PITFALLS — Lỗi Thường Gặp
Phần tiêu đề “6. PITFALLS — Lỗi Thường Gặp”| ❌ Sai Lầm | ✅ Đúng Cách |
|---|---|
| ”Refactor whole file" | "ONE smell fix first?” |
| Multiple change 1 commit | One logical change per commit |
| Refactor không có test | No test thì add test trước (Module 9.3) |
| Change logic while refactor | Refactor = same behavior, different structure |
| Không test sau mỗi step | Test EVERY increment. Non-negotiable. |
| Để Claude rewrite everything | Guide toward small, specific change |
| Refactor under deadline pressure | Don’t refactor if can’t do it right |
7. REAL CASE — Câu Chuyện Thực Tế
Phần tiêu đề “7. REAL CASE — Câu Chuyện Thực Tế”Scenario: E-commerce Việt Nam, legacy order processing — 800-line function, 5 năm patch, “works but don’t touch” reputation.
Failed attempt (big bang): Junior dev ask Claude “refactor function này.” Claude produce elegant rewrite. Break payment integration, shipping calculation, và audit logging. 3 ngày revert và recover.
Successful attempt (incremental):
- Tuần 1: Rename variable (15 commit, zero break)
- Tuần 2: Extract validation, processing, persistence (8 commit, 1 minor fix)
- Tuần 3: Extract shipping calculation vào service (4 commit)
- Tuần 4: Add proper error handling (6 commit)
Result: Same function, giờ 5 clean file, 33 commit, mỗi cái revertible. Zero production incident.
Quote: “Trick là bảo Claude ‘one small thing at a time.’ Nó muốn rewrite everything. Phải hold back.”
Tiếp theo: Module 9.3: Sinh test Legacy →