[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,94 +2,186 @@
id: wiki-2026-0508-switch-statements-switch-문
title: Switch Statements (Switch 문)
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: []
aliases: [Switch Statement, Pattern Matching, Replace Switch]
duplicate_of: none
source_trust_level: A
confidence_score: 0.92
tags: [uncategorized]
confidence_score: 0.9
verification_status: applied
tags: [refactoring, code-smell, polymorphism]
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: multi
framework: refactoring
---
# [[Switch Statements (Switch 문)]]
# Switch Statements (Switch 문)
## 📌 한 줄 통찰 (The Karpathy Summary)
Switch 문은 객체지향 프로그래밍에서 상속이나 다형성(Polymorphism)의 이점을 제대로 살리지 못하고 절차지향적으로 코드가 구현되었음을 나타내는 대표적인 '코드 스멜(OO Abusers)' 중 하나입니다 [1-3]. 이러한 조건문은 프로그램 여러 곳에 흩어져 코드 중복을 유발하며, 새로운 조건이 추가될 때마다 관련된 모든 Switch 문을 찾아 수정해야 하는 구조적 결함을 낳습니다 [2]. 일반적으로 '조건식을 다형성으로 바꾸기(Replace Conditional with Polymorphism)'와 같은 리팩토링 기법을 통해 이 문제를 해결하고 시스템의 유지보수성을 향상시킬 수 있습니다 [4, 5].
## 한 줄
> **"매 type-tagged switch 의 polymorphism 의 missed opportunity"**. 매 classic code smell 의 — 매 type 의 switch 의 새 type 의 추가 시 매 모든 switch 의 update 의 필요. 2026 의 modern lang 의 sealed types + pattern matching 의 acceptable.
## 📖 구조화된 지식 (Synthesized Content)
* **객체지향 설계의 결함 지표:** 객체지향 코드의 가장 뚜렷한 특징 중 하나는 Switch(또는 case) 문이 상대적으로 적다는 것입니다 [2]. Switch 문이 반복적으로 등장하는 것은 객체지향 구성 요소를 남용했거나(OO Abusers) 잘못 사용했다는 신호로 간주됩니다 [1, 3]. Switch 문의 근본적인 문제는 중복을 발생시킨다는 점이며, 새로운 분기 조건이 생길 때마다 흩어진 코드를 모두 수정해야 하므로 변경을 방해합니다 [2].
* **다형성을 활용한 리팩토링:** Switch 문을 마주치면 가장 먼저 다형성의 적용을 고려해야 합니다 [4].
* Switch 문이 종종 타입 코드(Type Code)를 기반으로 작동하는 경우, 우선 '함수 추출하기(Extract Method)'와 '함수 옮기기(Move Method)'를 사용해 해당 Switch 문을 다형성이 필요한 클래스로 이동시킵니다 [4].
* 그 다음 '타입 코드를 서브클래스로 바꾸기(Replace Type Code with Subclasses)'나 '타입 코드를 상태/전략 패턴으로 바꾸기(Replace Type Code with State/Strategy)'를 통해 상속 구조를 구축합니다 [4].
* 마지막으로 '조건식을 다형성으로 바꾸기(Replace Conditional with Polymorphism)'를 적용하여 분기 로직을 동적 바인딩으로 대체합니다 [4, 5]. 이를 통해 새로운 타입이 추가될 때 기존 코드를 수정할 필요가 없게 되어 개방-폐쇄 원칙(Open-Closed Principle)을 준수할 수 있습니다 [5, 6].
* **다형성 외의 대안 기법:** 조건이 Null인 경우를 처리하는 분기가 있다면 '널 객체 도입하기(Introduce Null Object)' 기법을 활용하여 Switch 문의 복잡성을 덜어낼 수 있습니다 [7].
## 매 핵심
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
* **다형성 적용의 오버엔지니어링(Overkill) 위험:** Switch 문을 제거하기 위해 무조건 다형성을 도입하는 것은 주의해야 합니다. 단일 메서드에만 영향을 미치는 소수의 조건 케이스만 존재하고 향후 이 조건들이 변경될 것으로 예상되지 않는 경우, 다형성을 도입하는 것은 오히려 불필요한 복잡성을 가중시키는 오버엔지니어링(Overkill)이 될 수 있습니다 [7].
* 이러한 제약 상황에서는 다형성 대신 '매개변수를 명시적 메서드로 바꾸기(Replace Parameter with Explicit Methods)'와 같이 더 단순한 리팩토링 방식을 선택하는 것이 타당합니다 [7].
### 매 왜 smell 인가
- **OCP 위반**: 매 새 type 의 추가 의 매 switch 의 modify 의 필요.
- **Shotgun surgery**: 매 동일 switch 의 codebase 의 scatter.
- **Type safety hole**: 매 default 의 fallthrough — 매 unhandled case 의 silent.
---
*Last updated: 2026-05-03*
### 매 acceptable cases
- Sealed/exhaustive matching (Kotlin, Rust, Swift, Java 21+).
- Single switch — 매 dispatch 의 한 곳.
- Performance-critical hot path (jump table).
- Parsing / state machines.
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
### 매 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 의 보장.
**언제 이 지식을 쓰는가:**
- *(TODO)*
### 매 응용
1. AST visitor (legitimate switch).
2. State machine (legitimate).
3. Domain logic dispatch (refactor to polymorphism).
**언제 쓰면 안 되는가:**
- *(TODO)*
## 💻 패턴
## 🧪 검증 상태 (Validation)
- **정보 상태:** needs_review
- **출처 신뢰도:** A
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
## 🧬 중복 검사 (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
### 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();
}
}
```
## 🤔 의사결정 기준 (Decision Criteria)
### 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()
```
**선택 A를 써야 할 때:**
- *(TODO)*
### 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
};
}
```
**선택 B를 써야 할 때:**
- *(TODO)*
### 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()
**기본값:**
> *(TODO)*
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
```
## ❌ 안티패턴 (Anti-Patterns)
### Rust — match
```rust
enum Msg { Quit, Move { x: i32, y: i32 }, Write(String) }
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
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<string, string> = { 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]]
- 변형: [[Pattern Matching]] · [[Polymorphism]] · [[Strategy Pattern]]
- 응용: [[State Machine]] · [[Visitor Pattern]] · [[ADT]]
- Adjacent: [[Open-Closed Principle]] · [[Sealed Classes]]
## 🤖 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 |