Capstone: Refactoring a Real Codebase for Quality
Clean Code, SOLID & Refactoring
Chapter 10 · Capstone: Refactoring a Real Codebase for Quality
One continuous worked project: TangleMart's order-processing system, genuinely tangled, refactored end to end using every technique from Chapters 1 through 9 — in the order the code's own dependencies actually force, not an arbitrary walkthrough order. Design Patterns' own capstone refactored a tangled function by applying patterns; this one refactors the same kind of tangle by fixing the underlying quality problems patterns are built on top of — naming, purity, parameter design, duplication, SOLID, and the refactoring catalog itself.
BaselineThe Tangled Starting Point
po(...) returning $41.00 (subtotal, discounted, plus shipping) while print_summary_bad(...) returned $36.00 — shipping was added to one duplicated copy and never to the other. This is Chapter 8's own duplicated-code finding, discovered in the wild rather than staged.
po() twice on the identical order (e.g. a retried request after a network blip) mutated inventory twice — widget dropped by 4 instead of 2. This is Chapter 3's exact impurity finding, reproduced.
Step 1Naming (Chapter 2)
po, t, i, oid, its, disc, ship are all renamed to process_order, total, item, order_id, items, discount, shipping before anything else happens — a pure rename, verified producing byte-identical output, exactly Chapter 2's own case for why naming is free to fix and costly to skip.
Step 2Extract Method, Purity & Move Method (Chapters 3, 5, 8)
checkout() and a new print_summary() both call the identical calculate_order_total() and now agree exactly, $41.00 both — resolving the baseline's own $41/$36 divergence. Calling print_summary() three times in a row left inventory completely untouched; a real checkout followed by a safe query-only retry left inventory decremented exactly once.
Step 3Long Parameter List (Chapter 4)
shipping and discount accidentally swapped returned $40.00 instead of the correct $41.00 — no error, no warning, a plausible-looking wrong number. Converting to keyword-only arguments (def calculate_order_total(*, items, shipping, discount)) made the identical mistake, attempted positionally, raise TypeError immediately, before any calculation ran — reproducing Chapter 4's own create_user_bad/create_user_good finding on this exact codebase's own function.
Step 4Replace Conditional with Polymorphism (Chapters 6, 8)
Both if/elif chains — discount and shipping — are replaced with DiscountStrategy and ShippingStrategy hierarchies, reusing the exact class shapes verified in Chapters 6 and 8.
SilverDiscount and EconomyShipping left NoDiscount, GoldDiscount, PlatinumDiscount, StandardShipping, ExpressShipping, and OvernightShipping all confirmed byte-identical via inspect.getsource() — all 6: True. SilverDiscount + EconomyShipping correctly computed $40.00 (40 × 0.95 + 2), matching a hand calculation exactly.
Step 5SOLID: LSP, ISP & DIP (Chapter 7)
Payment interface forced GiftCardPayment to implement refund(), which raised NotImplementedError: Gift cards can't be refunded the moment code written against the full Payment contract tried to use it — an LSP violation caught in the act. Segregating into Chargeable/Refundable means GiftCardPayment simply never claims to be Refundable (isinstance(GiftCardPayment(), Refundable) is correctly False) instead of lying about it and crashing later.
OrderService's source, captured before and after injecting a brand-new CryptoPayment class it had never seen, is confirmed byte-identical — the same dependency-inversion guarantee Software Architecture Fundamentals Chapter 7 verified for PricingEngine, reproduced here for payment methods specifically.
Step 6Debt Prioritization Retrospective (Chapter 9)
Applying Chapter 9's own interest = (severity − 1) × frequency formula to the three duplication/branching-shaped smells actually found in the baseline code, using each chain's own branch count (including the implicit "no match" path) as severity:
| Smell | Severity | Changes | Interest |
|---|---|---|---|
| Shipping if/elif chain | 4 branches | 9× | 27 |
| Duplicated total calc | 2 copies | 12× | 12 |
| Discount if/elif chain | 3 branches | 4× | 8 |
calculate_order_total to plug into. Combined, both conditional chains fixed together in Step 4 total 35 interest — 2.92× the duplication fix's own 12. The highest-value single step wasn't the one performed first; it was the one the earlier steps had to unlock.
Final Integration Check
print_summary() reports $41.00 with zero inventory mutation; checkout() via an injected CreditCardPayment charges the identical $41.00 and decrements inventory exactly once; two further print_summary() calls leave inventory unchanged; and swapping in a brand-new StoreCreditPayment — never seen by OrderService before — correctly charges the same order with zero changes to OrderService's own source. Every number matches the original baseline's own correct total, and every bug the baseline exhibited is now structurally impossible, not just fixed by coincidence.
What This Course Doesn't Cover
- Automated refactoring tooling (IDE-assisted extract/rename, static analysis linters) — this course covered the underlying judgment, not any specific tool
- Language-specific idioms beyond Python's own conventions used throughout
- The full Gang-of-Four pattern catalog — that's Design Patterns' own territory, reused here only where a pattern (Strategy) was the direct destination of a refactor
- Formal code review process, team conventions, or style-guide enforcement — reserved for the still-outstanding Software Development Lifecycle course
- Performance profiling or optimization — a clean design and a fast one are different concerns, covered by Technical Support's own diagnostic courses instead
Where This Connects
| This capstone's technique | Direct connection |
|---|---|
| Extract Method resolving a duplicated, diverged calculation | Chapter 8, and Design Patterns' own Strategy chapter — the same shape of fix, one course apart |
| Injected payment dependency, OrderService source unchanged across 3 types | Software Architecture Fundamentals Chapter 7's own ports-and-adapters finding, reproduced at class scale |
| Debt-interest ranking justifying which refactor mattered most | Chapter 9's own formula, applied retrospectively to a real, not hypothetical, codebase |
| Pseudocode & Algorithmic Problem-Solving's own decomposition discipline | The six-step refactor sequence itself — breaking one tangled function into independently verifiable pieces |
Hands-On Exercises
Add a fourth smell to this chapter's own Step 6 ranking table: the original 8-positional-parameter signature from Step 3, treating "adjacent same-typed parameters that could be silently swapped" (2: shipping/discount) as severity, changed 6 times over the same period. Compute its interest and determine where it lands in the full four-item ranking.
Add a PlatinumDiscount-equivalent tier to this chapter's own final integrated system — a LoyaltyDiscount class applying a 15% discount — and verify all pre-existing discount classes (NoDiscount, GoldDiscount) stay byte-identical, and that a full checkout using the new tier produces the correct total.
Add a second concurrent order to this chapter's own final integration check — a different item set, different discount and shipping strategies, checked out through the same OrderService instance used for the first order. Verify both orders' totals are correct and independent, and that inventory reflects both orders' own deductions correctly.
Chapter 10 Quick Reference — Course Summary
- Verified end to end: a genuinely tangled order processor, refactored in 6 dependency-ordered steps, each directly reusing a specific prior chapter's own verified technique
- Step 2 fixed a real divergence: $41.00 vs $36.00 in the baseline, both agreeing at $41.00 after Extract Method
- Step 3 turned a silent wrong answer into a loud error: $40.00 silently vs. an immediate TypeError
- Step 4 verified 6 strategy classes byte-identical after 2 real extensions
- Step 5 verified an LSP violation caught in the act, then fixed via ISP segregation and DIP injection, OrderService staying byte-identical across 3 payment types
- Step 6 verified the highest-interest fix (27) wasn't the one performed first — it was the one the earlier steps had to unlock
- Course complete: naming, purity, function design, code smells, SOLID, the refactoring catalog, and technical debt — all ten chapters, verified throughout