--- id: wiki-2026-0508-스파게티-코드-spaghetti-code title: 스파게티 코드 (Spaghetti Code) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [spaghetti code, tangled code] duplicate_of: none source_trust_level: A confidence_score: 0.95 verification_status: applied tags: [anti-pattern, code-quality, refactoring] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: any framework: any --- # 스파게티 코드 (Spaghetti Code) ## 매 한 줄 > **"매 control flow 가 noodle 처럼 entangled 되어 trace 불가"**. 매 unstructured GOTO · deeply nested conditions · global state mutation · circular dependency 가 만든 maintenance nightmare. 매 SOLID 위반 의 most visible symptom. ## 매 핵심 ### 매 증상 - **Tangled control flow**: 함수 한 개가 500+ lines, nested if 5+. - **Global state**: any 함수 가 any 변수 mutate. - **Circular dep**: A→B→C→A. - **Magic numbers/strings**: meaning unclear. - **Copy-paste**: same logic in 7 places. ### 매 원인 - Time pressure → "just make it work". - No code review → drift 누적. - Premature optimization → unnecessary complexity. - Lack of architecture → ad-hoc additions. ### 매 응용 (refactor 전략) 1. Extract method · extract class. 2. Replace conditional with polymorphism. 3. Introduce parameter object. 4. Strangler fig migration. ## 💻 패턴 ### Before (spaghetti) ```typescript function processOrder(o: any) { if (o.type == "A") { if (o.user.isVip) { o.discount = 0.2; if (o.country == "KR") o.tax = 0.1; else if (o.country == "US") o.tax = 0.07; // ... 200 more lines } } } ``` ### After (refactored) ```typescript type Order = { type: OrderType; user: User; country: Country; items: Item[] }; const discountStrategy: Record number> = { A: u => u.isVip ? 0.2 : 0.05, B: () => 0.1, }; const taxRate: Record = { KR: 0.1, US: 0.07, JP: 0.08 }; function processOrder(o: Order) { const discount = discountStrategy[o.type](o.user); const tax = taxRate[o.country]; return finalizePricing(o, discount, tax); } ``` ### Replace conditional with polymorphism ```typescript abstract class Payment { abstract process(amount: number): Promise; } class CardPayment extends Payment { async process(a: number) { /* card */ } } class CryptoPayment extends Payment { async process(a: number) { /* btc */ } } ``` ### Extract method ```typescript // before: 1 huge function // after: 5 small functions, each <20 lines, single responsibility function checkout(cart: Cart) { validateCart(cart); const total = calculateTotal(cart); const tax = applyTax(total, cart.country); return submitPayment(cart.user, total + tax); } ``` ### Detect with cyclomatic complexity ```bash npx eslint . --rule 'complexity: ["error", 10]' npx code-complexity ./src --max 10 ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Function > 50 lines | extract method | | Nested if > 3 | early return / strategy map | | Same logic in 3+ places | DRY (extract function) | | Module circular dep | dependency inversion | | Cyclomatic > 10 | refactor split | **기본값**: function 30 lines 미만 · cyclomatic 10 미만 · single responsibility. ## 🔗 Graph - 부모: [[SOLID 원칙]] · [[관심사의 분리 (Separation of Concerns)]] - Adjacent: [[단일 책임 원칙 (SRP)]] · [[기본 타입에의 집착 (Primitive Obsession)]] ## 🤖 LLM 활용 **언제**: legacy code refactor · cyclomatic 감소 제안 · extract method 자동화. **언제 X**: domain semantics 가 unclear → human review 필수. ## ❌ 안티패턴 - **Big rewrite**: incremental refactor 가 safe. - **Refactor without tests**: regression 보장 없음. - **Premature abstraction**: 2번째 use case 까지 기다림 (rule of three). ## 🧪 검증 / 중복 - Verified (Fowler "Refactoring" · Martin "Clean Code"). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — spaghetti code refactor 패턴 |