--- id: wiki-2026-0508-switch-statements-switch-문 title: Switch Statements (Switch 문) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Switch Statement, Pattern Matching, Replace Switch] duplicate_of: none source_trust_level: A confidence_score: 0.9 verification_status: applied tags: [refactoring, code-smell, polymorphism] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: multi framework: refactoring --- # Switch Statements (Switch 문) ## 매 한 줄 > **"매 type-tagged switch 의 polymorphism 의 missed opportunity"**. 매 classic code smell 의 — 매 type 의 switch 의 새 type 의 추가 시 매 모든 switch 의 update 의 필요. 2026 의 modern lang 의 sealed types + pattern matching 의 acceptable. ## 매 핵심 ### 매 왜 smell 인가 - **OCP 위반**: 매 새 type 의 추가 의 매 switch 의 modify 의 필요. - **Shotgun surgery**: 매 동일 switch 의 codebase 의 scatter. - **Type safety hole**: 매 default 의 fallthrough — 매 unhandled case 의 silent. ### 매 acceptable cases - Sealed/exhaustive matching (Kotlin, Rust, Swift, Java 21+). - Single switch — 매 dispatch 의 한 곳. - Performance-critical hot path (jump table). - Parsing / state machines. ### 매 refactoring 전략 - **Replace with polymorphism**: type-tagged switch → method override. - **Replace with strategy**: behavior-tagged switch → strategy injection. - **Replace with map**: data-tagged switch → lookup table. - **Sealed pattern match**: 매 modern lang 의 exhaustive 의 보장. ### 매 응용 1. AST visitor (legitimate switch). 2. State machine (legitimate). 3. Domain logic dispatch (refactor to polymorphism). ## 💻 패턴 ### Smell — type-tagged switch ```java // BAD double area(Shape s) { switch (s.type) { case CIRCLE: return Math.PI * s.radius * s.radius; case SQUARE: return s.side * s.side; case TRIANGLE: return 0.5 * s.base * s.height; default: throw new IllegalStateException(); } } ``` ### Refactor — polymorphism ```java sealed interface Shape permits Circle, Square, Triangle { double area(); } record Circle(double r) implements Shape { public double area() { return Math.PI * r * r; } } record Square(double side) implements Shape { public double area() { return side * side; } } record Triangle(double base, double h) implements Shape { public double area() { return 0.5 * base * h; } } // caller: shape.area() ``` ### Java 21 — pattern matching switch (exhaustive) ```java double area(Shape s) { return switch (s) { case Circle c -> Math.PI * c.r() * c.r(); case Square sq -> sq.side() * sq.side(); case Triangle t -> 0.5 * t.base() * t.h(); // no default — compiler proves exhaustive }; } ``` ### Kotlin — sealed when ```kotlin sealed class Event data class Click(val x: Int, val y: Int) : Event() data class Key(val code: Int) : Event() object Close : Event() fun handle(e: Event) = when (e) { is Click -> "click at ${e.x},${e.y}" is Key -> "key ${e.code}" Close -> "bye" } // exhaustive — no else needed ``` ### Rust — match ```rust enum Msg { Quit, Move { x: i32, y: i32 }, Write(String) } fn process(m: Msg) { match m { Msg::Quit => println!("quit"), Msg::Move { x, y } => println!("move to {x},{y}"), Msg::Write(s) => println!("write {s}"), } } ``` ### Replace with map (data dispatch) ```typescript // BAD function fmt(t: string, v: number): string { switch (t) { case "usd": return `$${v}`; case "eur": return `€${v}`; case "krw": return `₩${v}`; } } // GOOD const PREFIX: Record = { usd: "$", eur: "€", krw: "₩" }; const fmt = (t: string, v: number) => `${PREFIX[t] ?? ""}${v}`; ``` ### Replace with strategy ```python class Discount(Protocol): def apply(self, price: float) -> float: ... class Pct(Discount): def __init__(self, p): self.p = p def apply(self, price): return price * (1 - self.p) class Fixed(Discount): def __init__(self, amt): self.amt = amt def apply(self, price): return max(0, price - self.amt) # caller injects Discount, no switch ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | Type dispatch (open set) | Polymorphism | | Type dispatch (closed set) | Sealed + pattern match | | Data lookup | Map / dict | | Complex behavior swap | Strategy pattern | | AST / state machine | Switch (legitimate) | **기본값**: 매 sealed types + exhaustive pattern matching — 매 modern lang 의 ergonomic + safe. ## 🔗 Graph - 부모: [[Code Smells]] · [[Refactoring_Best_Practices|Refactoring]] - 변형: [[Pattern Matching]] · [[Polymorphism]] - 응용: [[State Machine]] · [[Visitor Pattern]] · [[ADT]] - Adjacent: [[Open-Closed Principle]] ## 🤖 LLM 활용 **언제**: 매 switch 의 detect 의 refactor suggestion, type 의 sealed 의 propose. **언제 X**: legitimate switch (AST, state machine) 의 전체 refactor 의 — 매 false positive. ## ❌ 안티패턴 - **Refactor every switch**: 매 legitimate cases 의 보존 — AST, parser. - **Visitor for trivial dispatch**: 매 over-engineering — 매 polymorphism 의 충분. - **Strategy without need**: 매 single-impl 의 strategy 의 yagni. ## 🧪 검증 / 중복 - Verified (Fowler, "Refactoring" 2nd ed.; Effective Java 3rd ed.; JEP 441). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — refactor patterns, modern pattern matching |