10장 흥미로운 시간.
10장에서는 공용 times를 제거하게 된다.
현재 두 클래스의 times는 비슷하다. 하지만 어떻게 처리해야 할 지 명백한 방법이 떠오르지 않는다.
그래서 팩토리 메서드를 적용하기 전으로 돌아가 본다.
Franc에서는 currency가 항상 "CHF", Dollor에서는 "USD"이므로 변수를 이용하도록 바꾼다.
이 때, 각 times()에서 Money를 반환할지, Dollor나 Franc를 반환 할 지 결정해야 한다.
우리는 Money로 공통되게 하고 싶다.
고민하는 대신 그냥 넣어보자.
현재는 Money가 추상클래스로 정의되어 있다.
추상클래스는 인스턴스를 반환할 수 없으므로 concrete클래스로 바꿔주라는 오류 메세지이다.
추상 메소드로 Money에 선언한 times() 메소드도 바꿔준다.
concrete 클래스로 바꾸고 테스트를 돌려 보니, 뭔가 일치하지 않는다.
이 메세지를 재대로 보기 위해 toString()을 정의한다.
그런데 테스트를 작성하지 않고 이 메소드를 정의한다?
여기서는 세가지 근거가 있다.
1. 화면에 나타나는 결과를 보려고 한다.
2. 디버그 출력에만 쓰이므로 잘못 구현됨에 따른 리스크가 적다.
3. 테스트가 실패하는 상황에서는 새로운 테스트를 또 작성하기는 부담이다.
테스트 파일을 보면 알겠지만, times()로 곱한 five객체의 currency가 null으로 나온다.
책에는 둘다 CHF로 나와야 하는데 왜 저렇게 나오는지 한참 고민해봤지만 모르겠다...
일단 책에 나온 대로 생각하고 진행해본다.
출력은 생각한 대로 나왔지만 클래스가 다르다.
expect는 Franc객체로 반환하고 있고, times()를 돌린 객체는 Money클래스의 객체를 반환하기 때문이다.
우리가 정말로 검사해야 할 것은 클래스가 같은지가 아니라, currency가 같은지이다.
이 문제는 Money의 equals()를 작성하면서도 꺼림직하게 생각했던 부분이다. 바꿔줘야 한다.
하지만 빨간막대상황에서는 새로운 코드를 작성하기 싫다. 그래서 테스트되는 초록막대 상태로 되돌아가 수정을 진행하고 싶다.
숙련되면 바로바로 할 수 있지만 이 방법이 보수적이고, 정석적인 TDD이다.
times()에서도 Franc를 반환하게 하니 테스트가 통과하는 모습이다.
우리는 Franc(10, "CHF") Money(10, "CHF") 이 둘이 같다고 나오고 싶은데 그렇지 않다고 나온 상황이다.
그대로 테스트에 추가해보자.
여전히 실패한다. 그럼 위에서 언급한 대로 currency를 비교하게 해보자.
이제 성공한다!
이젠 Franc클래스의 times가 Money를 반환하더라도 currency가 같기 때문에 성공한다.
이와 같이 Dollor를 바꿔도 동작하기 때문에 드디어 두 클래스의 times()의 모양을 같게 만들었다.
그럼 이제 Money클래스로 push up!
<할일 목록>
$5 + 10CHF = $10(환율이 2:1 인 경우)
// 해결 // $5 x 2 = $10
// 해결 // amount를 private로 만들기
// 해결 // Dollor 부작용?
Money 반올림
// 해결 // equals()
hashCode()
Equal null
Equal object
//해결// 5CHF x 2 = 10CHF
Dollor,Franc 중복
//해결// 공용 equal
//해결// 공용 times
//해결// Franc와 Dollor비교하기
//해결// 통화
testMultiplication2 삭제?
이 장에서 한 것을 정리해보면,
1. times()를 일치시키기 위해 그 메서드들이 호출하는 다른 메서드들을 인라인 시킨 후 상수 변수로 바꿈.
2. 디버깅을 위해 toString()작성
3. Franc대신 Money를 반환하도록 바꾸어 잘 작동하는지 컴퓨터에게 확인시킴.
4. 실험 했던 것을 뒤로 물리고, 다른 테스트를 작성했다. 그랬더니 테스트가 잘 돌아갔다.
5. 그를 바탕으로 공통부분을 만들고, push up했다.
11장 모든 악의 근원.
이젠 Dollor와 Franc에 생성자 메소드밖에 남지 않았다. 이는 아무 의미가 없으므로, 빨리 없애보자.
Money클래스에서 하위 클래스를 참조하는 메소드를 찾아보자.
이 두놈이 되겠다.
둘다 Money를 반환하도록 바꾼다.
이제 코드상으로 하위 클래스는 참조하지 않는다.
이제 Dollor, Franc클래스를 쓰레기통에 버려버리자.
그랬더니 테스트에 빨간줄이 떳다.
저번 장에서 작성한 테스트이다.
이 클래스대신 currency를 비교하는 코드는 클래스가 여러가지 있을 때, 도움되는 코드이다.
우리는 지금 클래스를 하나만 남기는 과정을 하고 있으므로, 이 테스트는 짐이 된다.
그리고 testEquality()의 세번째, 네번째는 적혀있는 대로 중복이다. 첫번째, 두번제 단언과 중복되므로 이것도 짐.
짐이 되는 것을 모두 삭제한다.
이와 비슷하게 Multiplication, Multiplication2 테스트는 Dollor와 Franc 두 클래스가 존재했을 때 의미가 있다.
하지만 지금은 Money클래스만 남았으니 두 테스트의 차이가 없다.
따라서 testMultiplication2도 삭제가능하다.
'책읽기 > TDD:ByExample' 카테고리의 다른 글
TDD_8 (0) | 2020.11.22 |
---|---|
TDD_7 (0) | 2020.11.17 |
TDD_5 (0) | 2020.11.10 |
TDD_4(값 객체 패턴) (0) | 2020.11.08 |
TDD_3 (0) | 2020.11.06 |