--- id: wiki-2026-0508-extract-method-함수-추출하기 title: Extract Method (함수 추출하기) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Extract Function, 함수 추출] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [refactoring, clean-code, method] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: refactoring --- # Extract Method (함수 추출하기) ## 매 한 줄 > **"매 code fragment 가 의도를 가질 때, 매 그 의도를 이름으로 만든다"**. 매 Fowler *Refactoring* (1999, 2018) 의 매 most-used refactoring — 매 long method 를 작은 well-named function 으로 쪼개 매 readability + reusability 의 동시 확보. 2026 IDE (IntelliJ, VS Code, Cursor) 의 자동 refactor 로 매 cost 가 사실상 0. ## 매 핵심 ### 매 trigger - 매 method 가 한 화면을 넘는다. - 매 comment 로 "이 부분은 X 한다" 라고 설명하고 있다 → 매 그 X 가 method name. - 매 동일 logic 의 duplication. - 매 nested conditional 의 가독성 hurt. ### 매 mechanic (Fowler) 1. 매 새 함수 의 create — intent-revealing name. 2. 매 fragment 를 새 함수로 copy. 3. 매 local variable 의 scope 분석 → parameter / return value 결정. 4. 매 원래 자리에 call 로 replace. 5. 매 test 실행 (매 step 마다). ### 매 응용 1. Long Method 의 fix. 2. Duplicate Code 의 removal. 3. Replace Temp with Query 의 stepping stone. 4. 매 LLM-assisted refactor 의 safest primitive. ## 💻 패턴 ### Before (long method) ```ts function printOwing(invoice: Invoice) { let outstanding = 0; console.log("***********************"); console.log("**** Customer Owes ****"); console.log("***********************"); for (const o of invoice.orders) outstanding += o.amount; const today = new Date(); invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30); console.log(`name: ${invoice.customer}`); console.log(`amount: ${outstanding}`); console.log(`due: ${invoice.dueDate.toLocaleDateString()}`); } ``` ### After (extracted) ```ts function printOwing(invoice: Invoice) { printBanner(); const outstanding = calculateOutstanding(invoice); recordDueDate(invoice); printDetails(invoice, outstanding); } function printBanner() { console.log("***********************"); console.log("**** Customer Owes ****"); console.log("***********************"); } function calculateOutstanding(invoice: Invoice): number { return invoice.orders.reduce((sum, o) => sum + o.amount, 0); } function recordDueDate(invoice: Invoice) { const today = new Date(); invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30); } function printDetails(invoice: Invoice, outstanding: number) { console.log(`name: ${invoice.customer}`); console.log(`amount: ${outstanding}`); console.log(`due: ${invoice.dueDate.toLocaleDateString()}`); } ``` ### Extract with multiple return (TS tuple) ```ts function summarize(xs: number[]): { sum: number; avg: number } { return { sum: total(xs), avg: total(xs) / xs.length }; } function total(xs: number[]) { return xs.reduce((a, b) => a + b, 0); } ``` ### Extract from conditional (Decompose Conditional) ```ts // before if (date.before(SUMMER_START) || date.after(SUMMER_END)) charge = qty * winterRate + winterFee; else charge = qty * summerRate; // after charge = isSummer(date) ? summerCharge(qty) : winterCharge(qty); function isSummer(d: Date) { return !d.before(SUMMER_START) && !d.after(SUMMER_END); } ``` ### IDE shortcut (VS Code / Cursor) ``` Select code → Cmd+. → "Extract to function in module scope" # 매 zero-cost — 매 Fowler 가 1999 에 손으로 하던 것 ``` ### LLM-assisted (Claude Code) ``` "이 함수에서 outstanding 계산 부분을 calculateOutstanding 으로 extract" → 매 LLM 이 mechanic 의 1-5 를 자동 수행 + test 보존 검증 ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Fragment 에 의도 있음 | Extract Method | | Single expression with confusing name | Extract Variable | | Class 가 너무 비대 | Extract Class (after multiple Extract Method) | | 매 한 번만 쓰이고 trivial | 매 inline 유지 — 매 over-extraction 회피 | **기본값**: 매 의심되면 extract — 매 IDE 가 자동, 매 inline 으로 되돌리기도 trivial. ## 🔗 Graph - 부모: [[Refactoring_Best_Practices|Refactoring]] · [[Clean Code]] - 변형: [[Extract Class]] - Adjacent: [[Inline Method]] (매 inverse) · [[Single Responsibility]] ## 🤖 LLM 활용 **언제**: 매 long method / duplicated block 발견 시 즉시 propose. **언제 X**: 매 hot path 의 micro-optimization (function call overhead) — 매 측정 기반. ## ❌ 안티패턴 - **Over-extraction**: 매 1-2 line trivial 도 extract → 매 indirection 폭발. - **Bad name**: `helper1`, `doStuff` — 매 의도 의 표현 실패. - **Hidden side effect**: 매 pure name 으로 보이는데 매 mutation 수행. - **Premature extraction without test**: 매 mechanic step 5 건너뛰기 → silent regression. ## 🧪 검증 / 중복 - Verified (Fowler *Refactoring* 2nd ed. 2018 Ch. 6, Beck *Tidy First?* 2024). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — Fowler mechanic + modern IDE/LLM workflow 정리 |