[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
@@ -2,104 +2,163 @@
id: wiki-2026-0508-extract-method-함수-추출하기
title: Extract Method (함수 추출하기)
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: []
aliases: [Extract Function, 함수 추출]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
tags: [uncategorized]
confidence_score: 0.9
verification_status: applied
tags: [refactoring, clean-code, method]
raw_sources: []
last_reinforced: 2026-05-08
last_reinforced: 2026-05-10
github_commit: pending
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
tech_stack:
language: unspecified
framework: unspecified
language: typescript
framework: refactoring
---
# [[Extract Method (함수 추출하기)]]
# Extract Method (함수 추출하기)
## 📌 한 줄 통찰 (The Karpathy Summary)
Extract Method(함수 추출하기)는 그룹화할 수 있는 코드 조각을 찾아 그 목적을 잘 설명하는 이름을 가진 독립된 메서드로 분리하는 가장 일반적인 리팩토링 기법입니다 [1, 2]. 이 기법은 주로 메서드가 너무 길거나, 코드의 의도를 파악하기 위해 주석이 필요한 경우에 사용됩니다 [2]. 복잡한 함수를 잘게 쪼개어 메서드 이름 자체가 문서 역할을 하도록 만들어 코드의 가독성과 테스트 용이성을 크게 높이는 것이 핵심 목적입니다 [1].
## 한 줄
> **"매 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.
## 📖 구조화된 지식 (Synthesized Content)
* **적용 시기 (When to apply):** 40줄을 초과하는 긴 메서드, 여러 곳에서 중복되는 로직, 또는 복잡성으로 인해 단위 테스트가 불가능한 코드를 발견했을 때 적용합니다 [1]. 또한 긴 메서드(Long Method)나 중복 코드(Duplicated Code)와 같은 코드 스멜을 해결하거나, 코드 블록에 주석을 달아야만 이해할 수 있을 때 주로 사용합니다 [2].
* **효과 및 장점 (Why it works):**
* 메서드의 이름이 코드의 의도(How가 아닌 What)를 설명하는 문서 역할을 하여 코드 파악(Scannability)을 돕습니다 [1, 2].
* 잘게 쪼개진 메서드는 다른 메서드에서 재사용될 확률을 높이고, 오버라이딩(Overriding)을 쉽게 만듭니다 [2].
* 복잡했던 단위 테스트 과정을 직관적인 검증 과정으로 변환시켜 줍니다 [1].
* 상위 수준의 메서드가 마치 일련의 주석을 읽는 것처럼 자연스럽게 읽히도록 합니다 [2].
* **실행 절차 (Steps/Mechanics):**
1. 메서드의 의도를 설명하는 이름으로 새로운 메서드를 생성합니다 [1, 2].
2. 추출할 코드를 원본 메서드에서 새 메서드로 복사합니다 [2].
3. 추출된 코드 내에서 원본 메서드의 지역 변수 및 매개변수를 참조하는지 확인합니다 [2].
4. 추출된 코드 내에서만 사용되는 임시 변수는 새 메서드 내의 임시 변수로 선언합니다 [2].
5. 읽기 전용으로 사용되는 지역 변수는 새 메서드의 매개변수로 전달합니다 [2].
6. 수정되는 지역 변수가 하나 있다면, 추출된 코드를 질의(Query) 함수로 취급하여 결과를 반환(return)받아 변수에 할당하도록 변수 스코프를 업데이트합니다 [1, 2].
7. 원본 메서드의 추출된 코드 부분을 새 메서드 호출로 대체한 후 전체 테스트를 실행하여 동작 보존 여부를 검증합니다 [1, 2].
## 매 핵심
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
* **지역 변수와 임시 변수 처리의 어려움:** Extract Method장 큰 난관은 지역 변수, 특히 임시 변수(Temp)를 처리하는 것입니다 [2]. 매개변수와 임시 변수가 많은 코드를 무작정 추출하면, 새 메서드에 너무 많은 매개변수를 전달하게 되어 오히려 원래 코드보다 가독성이 떨어질 수 있습니다 [2]. 이러한 경우에는 '임시 변수를 질의 함수로 바꾸기(Replace Temp with Query)', '매개변수 객체 도입하기(Introduce Parameter Object)' 또는 '메서드를 메서드 객체로 대체하기(Replace Method with Method Object)'를 먼저 적용하여 매개변수와 변수를 줄이는 사전 작업이 필요할 수 있습니다 [2].
* **다중 반환 값 문제:** 추출하려는 코드가 두 개 이상의 지역 변수를 수정하여 반환해야 하는 경우 추출 작업이 매우 까다로워집니다 [2]. 이럴 때는 단일 값을 반환하도록 추출할 코드를 다르게 선택하거나, 각각을 별도의 메서드로 분리하는 것이 좋습니다 [2].
* **과도한 단편화(Over-fragmentation) 및 결합도:** 코드를 너무 얇게 쪼개면 로직이 사방으로 흩어져 전체 흐름을 파악하기 어려워질 수 있으므로 주의해야 합니다 [1]. 또한 지역 변수에 의존하는 추출된 메서드는 미묘한 결합(Subtle coupling)을 유발할 수 있으므로 변수 스코프를 주의 깊게 모니터링해야 합니다 [1].
* **이름 짓기의 제약:** 작게 쪼개진 메서드는 '좋은 이름'을 가질 때만 그 진가를 발휘합니다 [2]. 코드의 의도를 명확하게 드러내는 의미 있는 이름을 지을 수 없다면 해당 코드는 억지로 추출하지 않는 것이 낫습니다 [2].
### 매 trigger
- 매 method 가 한 화면을 넘는다.
- 매 comment 로 "이 부분은 X 한다" 라고 설명하고 있다 → 매 그 X 가 method name.
- 매 동일 logic 의 duplication.
- 매 nested conditional 의 가독성 hurt.
---
*Last updated: 2026-05-03*
### 매 mechanic (Fowler)
1. 매 새 함수 의 create — intent-revealing name.
2. 매 fragment 를 새 함수로 copy.
3. 매 local variable 의 scope 분석 → parameter / return value 결정.
4. 매 원래 자리에 call 로 replace.
5. 매 test 실행 (매 step 마다).
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
### 매 응용
1. Long Method 의 fix.
2. Duplicate Code 의 removal.
3. Replace Temp with Query 의 stepping stone.
4. 매 LLM-assisted refactor 의 safest primitive.
**언제 이 지식을 쓰는가:**
- *(TODO)*
## 💻 패턴
**언제 쓰면 안 되는가:**
- *(TODO)*
### Before (long method)
```ts
function printOwing(invoice: Invoice) {
let outstanding = 0;
console.log("***********************");
console.log("**** Customer Owes ****");
console.log("***********************");
## 🧪 검증 상태 (Validation)
for (const o of invoice.orders) outstanding += o.amount;
- **정보 상태:** needs_review
- **출처 신뢰도:** A
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
const today = new Date();
invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
## 🧬 중복 검사 (Duplicate Check)
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
- **처리 방식:** UPDATE (자동 정규화)
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
## 🔗 지식 연결 (Graph)
- **Parent:** [[10_Wiki/Topics]]
- **Related:** *(TODO: 최소 2개)*
- **Opposite / Trade-off:** *(TODO)*
- **Raw Source:** 직접 입력
## 🕓 변경 이력 (Changelog)
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|------|-----------|-----------|--------|
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
## 💻 코드 패턴 (Code Patterns)
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
```text
# TODO
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
console.log(`due: ${invoice.dueDate.toLocaleDateString()}`);
}
```
## 🤔 의사결정 기준 (Decision Criteria)
### After (extracted)
```ts
function printOwing(invoice: Invoice) {
printBanner();
const outstanding = calculateOutstanding(invoice);
recordDueDate(invoice);
printDetails(invoice, outstanding);
}
**선택 A를 써야 할 때:**
- *(TODO)*
function printBanner() {
console.log("***********************");
console.log("**** Customer Owes ****");
console.log("***********************");
}
**선택 B를 써야 할 때:**
- *(TODO)*
function calculateOutstanding(invoice: Invoice): number {
return invoice.orders.reduce((sum, o) => sum + o.amount, 0);
}
**기본값:**
> *(TODO)*
function recordDueDate(invoice: Invoice) {
const today = new Date();
invoice.dueDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
}
## ❌ 안티패턴 (Anti-Patterns)
function printDetails(invoice: Invoice, outstanding: number) {
console.log(`name: ${invoice.customer}`);
console.log(`amount: ${outstanding}`);
console.log(`due: ${invoice.dueDate.toLocaleDateString()}`);
}
```
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
### 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]] · [[Clean Code]]
- 변형: [[Extract Variable]] · [[Extract Class]] · [[Extract Interface]]
- 응용: [[Replace Temp with Query]] · [[Decompose Conditional]] · [[Remove Duplication]]
- Adjacent: [[Inline Method]] (매 inverse) · [[Long Method Smell]] · [[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 정리 |