Skip to content

Commit 252fe60

Browse files
committed
docs(chapter10): enhance examples and refactor analysis for Special Case pattern
1 parent 8c8bd52 commit 252fe60

File tree

1 file changed

+57
-3
lines changed

1 file changed

+57
-3
lines changed

chapter10/src/case05/README.md

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,62 @@ class UnknownCustomer:
5454

5555
## 예시
5656

57-
3번을 하는 게 보통 까다로운 작업이 아니다. 따라서 이 때는 함수로 추출하는 테크닉을 쓰자
57+
### 1번 예시
5858

59-
7번도 재밌(?)는데, 각 클라이언트에서 수행하는 특이 케이스 검사를 일반 기본값으로 대체 가능하면, 여러 함수를 클래스로 묶기 처리가 가능하다.
59+
- 3번을 하는 게 보통 까다로운 작업이 아니다. 따라서 이 때는 함수로 추출하는 테크닉을 쓰자
60+
- 7번도 재밌(?)는데, 각 클라이언트에서 수행하는 특이 케이스 검사를 일반 기본값으로 대체 가능하면, 여러 함수를 클래스로 묶기 처리가 가능하다.
61+
- 만약 없는 케이스면 `customer_name = "occupant"` 로 처리한다. 이를 UnknownCustomer의 메소드로 쓰면?
62+
- 핵심은, 코드 속에 반복되던 if-else를 뺐다는 것이다. 특수 케이스 객체는 동일한 인터페이스를 제공하니까, 뭘 다루는지는 사실 관심 밖으로 둬도 된다.
63+
64+
감이 안 와서, 클로드 3.7 Sonnet에게 리뷰한 내용을 기록해둔다.
65+
66+
<details>
67+
<summary>자세히</summary>
68+
69+
# 리팩터링 분석: Special Case 패턴 적용 결과
70+
71+
원래 JavaScript 코드와 최종 Python 코드를 비교해보면, "Introduce Special Case" 패턴을 적용한 결과 코드가 상당히 개선되었습니다.
72+
73+
## 개선된 점
74+
75+
1. **조건문 제거**: 가장 큰 개선점은 `a_customer === "unknown"` 같은 조건문이 완전히 제거되었습니다. 이전에는 여러 함수에서 동일한 조건 검사를 반복했지만, 이제는 다형성을 통해 해결합니다.
76+
77+
2. **객체 일관성**: 이전에는 `customer`가 때로는 문자열("unknown"), 때로는 객체(Customer 인스턴스)였습니다. 이제는 항상 객체(Customer 또는 UnknownCustomer)이므로 인터페이스가 일관됩니다.
78+
79+
3. **코드 단순화**: 클라이언트 코드가 매우 단순해졌습니다. 예를 들어:
80+
- 이전: `const weeksDelinquent = (aCustomer === "unknown") ? 0 : aCustomer.paymentHistory.weeksDelinquentInLastYear;`
81+
- 이후: `return site.customer.payment_history.weeks_delinquent_in_last_year;`
82+
83+
4. **객체 지향적 접근**: 특수 케이스를 위한 전용 클래스(UnknownCustomer)와 하위 객체(NullPaymentHistory)를 만들어 객체 계층을 활용합니다.
84+
85+
5. **확장성 향상**: 새로운 요구사항이 생겨도 기존 코드 수정 없이 UnknownCustomer 클래스만 수정하면 됩니다(Open-Closed Principle).
86+
87+
## 패턴 적용 내용
88+
89+
1. **UnknownCustomer 클래스 생성**: 특수 케이스를 위한 전용 클래스를 만들어 "unknown" 고객을 표현합니다.
90+
91+
2. **NullPaymentHistory 클래스 생성**: 특수 케이스에서 필요한 하위 객체도 객체로 구현했습니다.
92+
93+
3. **Site 클래스 수정**: 생성자에서 문자열을 객체로 변환하여 일관된 인터페이스를 제공합니다.
94+
95+
4. **클라이언트 코드 단순화**: 모든 분기 처리를 제거하고 다형성에 의존합니다.
96+
97+
## 마틴 파울러의 "Introduce Special Case" 패턴 적용
98+
99+
이 리팩터링은 마틴 파울러의 "Introduce Special Case" 패턴을 정확히 따릅니다:
100+
- 반복되는 특수 케이스 검사를 제거합니다
101+
- 특수 케이스 객체가 일반 객체와 동일한 인터페이스를 제공합니다
102+
- 클라이언트 코드는 어떤 타입의 객체를 다루는지 알 필요가 없습니다
103+
104+
## 결론
105+
106+
이 리팩터링의 핵심 이점은 **코드의 복잡성 감소**와 **유지보수성 향상**입니다. 각 함수에 반복되던 if-else 분기가 제거되어 코드의 가독성이 크게 개선되었고, 새로운 동작이 필요할 때도 기존 코드를 수정하는 대신 특수 케이스 클래스만 수정하면 됩니다.
107+
108+
이것이 바로 마틴 파울러가 "Introduce Special Case" 패턴을 통해 달성하고자 한 목표입니다 - 특수 케이스 처리를 위한 반복적인 조건문을 다형성을 활용한 객체 지향적 해결책으로 대체하는 것입니다.
109+
110+
</details>
111+
112+
### 2번 예시
113+
114+
데이터 구조를 _읽기만 하면_ 리터럴 객체를 둬도 무방하다.
60115

61-
만약 없는 케이스면 `customer_name = "occupant"` 로 처리한다. 이를 UnknownCustomer의 메소드로 쓰면?

0 commit comments

Comments
 (0)