11장 - 모든 악의 근원
11장에서는 불필요해진 하위 클래스 Dollar
와 Franc
을 제거한다. 이 때, 무작정 삭제부터 해버리는 것이 아니라 참조하는 곳을 찾아 상위 클래스 Money
로 치환부터 한다. 선 치환 후 삭제인 것이다. 이런 식으로 해야 나중에 하위 클래스를 삭제함으로써 야기되는 부작용들이 최소화될 것으로 생각된다.
그리고 관련 테스트 역시 상위클래스로 모두 바꿔주고 필요 없어진 테스트는 지워준다.
모든 악의 근원이 정확하게 무엇인 지는 모르겠지만, 불필요한 하위 클래스가 포함되는 것은 틀림없다.
12장 - 드디어 더하기
저자는 12장의 주제대로 화폐끼리 더하는 기능을 TDD를 통해 구현한다.
TDD 사이클의 크기
Money plus(Money added) {
return new Money(amount + addend.amount, currency);
}
저자는 간단한 테스트 코드를 미리 작성하고, 곧바로 프로덕션 코드를 작성한다. 이 때 작성된 테스트에 따라 가짜구현으로 조금씩 프로덕션 코드를 작성해나갈 수 도 있지만, 어떻게 구현해야 할 지 명확하게 아는 상황이므로 바로 구현한다.
그리고는 이런 말을 덧붙인다.
어떻게 설계해야 할지 명백하지 않으면 다시 가짜 구현을 하고 리팩토링하는 식으로 접근할 것이다. 이를 통해 TDD를 하면서 어떻게 단계의 크기를 조절할 수 있는지 배우기 바란다. (P. 114)
이전 장들에서도 몇 번 나왔던 얘기지만 TDD를 학습, 사용하면서 매우 중요한 부분이라 생각되어 다시 한 번 옮겨봤다.
개인적으로 TDD를 하면서 가장 나를 괴롭히는 것이 한 사이클에 어디까지 구현을 해야할 지를 모르는 것이다.
저자는 이렇 듯 구현할 내용을 명확하게 알면 한 번에 좀 크게해보기도 하고, 아니면 매우 작게 쪼개보기도 하면서 본인 스타일에 맞는 TDD를 깨우치길 바라는 것 같다.
즉, TDD 사이클의 크기에는 정답은 없는 것이다. 작게만 하라고 해서 무작정 쪼개기만 하지말고, 나만의 개발방법과 철학을 만들어보는 것도 좋을 것 같다.
Expression
화폐를 더하는 과정에서 다중 통화의 연산을 위해 Expression
(식) 이라는 인터페이스를 만들었다. Money
를 더하는 연산의 피연산자와 결과가 모두 화폐이기 때문에 Money
는 Expression
을 구현해도 아무 문제가 없을 것이다.
그런데 만약 통화가 서로 다른 Money
를 연산해야하는 경우 어떻게 해야할까?
12장의 제목을 드디어 더하기라고 했지만 아직 더하지 않았다. 다음 장으로 넘어가보자.
13장 - 진짜로 만들기
해당 장에서는 reduce
메서드가 주인공이다.
reduce
의 사전적 의미는 축약, 변형 등의 의미를 가지고 있다. 그래서인 지 Bank
, Money
, Sum
객체가 각각 가지고 있는 reduce
가 무엇을 뜻하는 지 헷갈렸다.
내가 봤을 땐 여기서 다루는 reduce
는 축약보다 변형의 의미인 것 같다. 옮긴이는 축약이라는 단어로 reduce
를 표현하는데, 실제 reduce
메서드들이 하는 행위가 무엇인 지 생각해보면 축약보다는 변형하는 것이라고 느꼈다.
예컨대, Bank
의 reduce
는 어떤 Expression
(Money
나 Sum
)과 통화(currency) 문자열이 매개변수로 들어왔을 때, 해당 Expression
을 해당 통화로 변형해서 Money
로 반환해주는 역할을 한다.
Money
의 reduce
역시 변형이다.
다만 Sum
의 reduce
는 조금 다르다. Sum
이 가지고 있는 augend
와 addend
를 원하는 통화로 변형한 다음, 둘을 더한 값을 반환한다. 변형과 축약을 모두 가지고 있는 셈이다.
reduce
가 아닌 다른 메서드 명을 사용했다면 더 좋지 않았을까 라는 생각이다.
억지로 추상화를 하려다 보니 중의적인 메서드 명을 사용해야 하는 부작용이라고도 느껴졌다.
이 역시 리팩터링 대상이 될 수도 있겠다.
14장 - 바꾸기(Change)
지금은 환율을 다음과 같이 가지고 있었다.
class Bank {
int rate(String from, String to) {
return (from.equals("CHF") && to.equals("USD")) ? 2 : 1;
return new Money(amount / rate, to);
}
}
이런 식이면 상수가 매번 Bank
객체 내부에 있어야한다. 이를 없애기 위해 Hashtable을 사용하여 통화와 환율을 메모리에 저장해둘 수 있다.
HashMap<Pair, Integer> rates = new HashMap<>();
Pair
클래스를 만들 때 테스트를 작성하지 않았다. 이유는 리팩터링 단계에서 코드를 작성했기 때문이다. 리팩터링 시에 프로덕션 코드를 작성했더라도 테스트가 통과하면 잘 작동되고 있다고 생각하고 넘어가기도 한다.
15장 - 서로 다른 통화 더하기
드디어 통화 더하기의 마지막 단계이다.
이 장에서는 계산단계에 사용되는 모든 Money
와 Sum
을 Expression
으로 수정해주었다.
정리
15장까지 TDD로 달려오며 느낀 TDD의 주요 골자는 다음과 같다.
- 중복제거
- 중복이 어디에 있든간에 어떻게든 없앤다.
- 중복이 제거되지 않았다면, 해당 테스트는 종료되었다고 할 수 없다.
- 추상화
- 추상화 역시 중복제거의 결과이다.
- 개발자는 추상화를 얼마나 잘하냐가 중요한데, TDD와 중복제거를 하다보면 자연스레 추상화가 된다.
Dollar
와Franc
을Money
로 추상화하고,Money
와Sum
을Expression
으로 다시 한 번 추상화하였다.- 추상화를 하려고 한 것이 아니라 중복제거의 결과였다는 것이 중요하다.
'외부활동' 카테고리의 다른 글
[NEXTSTEP] 3주차 정리 (0) | 2024.03.24 |
---|---|
[NEXTSTEP] 2주차 정리 (2) | 2024.03.17 |
[TDD 스터디] 테스트 주도 개발 6장 ~ 10장 (0) | 2024.03.10 |
[NEXTSTEP] 1주차 정리 (0) | 2024.03.10 |
[NEXTSTEP] TDD, 클린코드 with Java 18기 시작!! (0) | 2024.03.09 |