"매 refactoring = 매 외부 동작은 그대로 두고 internal 구조만 개선하는 disciplined transformation.". 매 Martin Fowler 1999 "Refactoring" 이 catalog 화한 70+ named transformation 이 backbone, 매 2026 현재 IDE automated refactor + LLM-assisted refactor (Claude Opus 4.7, Cursor) 가 manual rewrite 대체. 매 핵심 disciplines = small steps + green tests + commit per refactor.
매 핵심
매 catalog (대표)
Extract Function / Method: 매 코드 블록 → 새 function.
Inline Function: 매 trivial wrapper 제거.
Rename: 매 의미 명확한 이름.
Extract Variable / Inline Variable.
Move Function / Field: 매 right class/module 로.
Replace Conditional with Polymorphism.
Replace Magic Number with Constant.
Introduce Parameter Object.
Decompose Conditional.
Extract Class / Inline Class.
매 disciplines
Tests first: 매 refactor 전 green test suite.
Small steps: 매 single refactor → run tests → commit.
No mixing: 매 behavior change 와 refactor 동시 X.
Reversibility: 매 step 별 git revert 가능.
매 응용
Legacy modernization: 매 strangler fig + extract.
Performance: 매 inline hot function, extract slow path.
// BEFORE
functionpay(employee: Employee){switch(employee.type){case'engineer':returnbaseSalary(employee);case'salesman':returnbaseSalary(employee)+commission(employee);case'manager':returnbaseSalary(employee)+bonus(employee);}}// AFTER
abstractclassEmployeeType{abstractpay(e: Employee):number;}classEngineerextendsEmployeeType{pay(e){returnbaseSalary(e);}}classSalesmanextendsEmployeeType{pay(e){returnbaseSalary(e)+commission(e);}}classManagerextendsEmployeeType{pay(e){returnbaseSalary(e)+bonus(e);}}
// BEFORE
if(date.before(SUMMER_START)||date.after(SUMMER_END)){charge=quantity*winterRate+winterServiceCharge;}else{charge=quantity*summerRate;}// AFTER
charge=isSummer(date)?summerCharge(quantity):winterCharge(quantity);functionisSummer(d){return!d.before(SUMMER_START)&&!d.after(SUMMER_END);}functionsummerCharge(q){returnq*summerRate;}functionwinterCharge(q){returnq*winterRate+winterServiceCharge;}
Strangler Fig (legacy migration)
// route table — gradually shift endpoints to new service
constroutes={'/users':process.env.NEW_USERS==='on'?newUsers : legacyUsers,'/orders':process.env.NEW_ORDERS==='on'?newOrders : legacyOrders,'/billing':legacyBilling,// not migrated yet
};// flip flags one at a time, rollback by env var
# 1. select scope, 2. generate diff, 3. tests must stay green
claude refactor \
--scope src/billing/ \
--instruction "Extract OrderTotalCalculator class; preserve all behavior"\
--validate "pytest tests/billing/"# Claude proposes diff → run tests → commit if green
Test characterization (legacy without tests)
# Before refactor of untested code: write golden tests firstdeftest_legacy_charge_2025_invoice():inv=load_fixture('2025_invoice.json')expected=legacy.calc(inv)# capture current behaviorassertrefactored.calc(inv)==expected# equality, not "correctness"
매 결정 기준
상황
Refactor
Long function (> 30 lines)
Extract Function
Same param list 5+ places
Introduce Parameter Object
switch (type) repeated
Replace Conditional with Polymorphism
Confusing name
Rename
Class doing 2 things
Extract Class
Legacy without tests
Characterization tests first
Mass code movement
LLM batch + test-gate
기본값: small step + commit per refactor + tests green; LLM 으로 mass rename / extract 가속.