2장. 타락한 객체

변주한·2022년 6월 4일
0

일반적인 TDD 주기

  1. 테스트를 작성한다.
    • 마음 속에 있는 오퍼레이션이 코드에 어떤 식으로 나타나길 원하는지 생각해보라.
    • 이야기를 써내려가는 것이다.
    • 원하는 인터페이스를 개발하라.
    • 올바른 답을 얻기 위해 필요한 이야기의 모든 요소를 포함시켜라.
  2. 실행 가능하게 만든다.
    • 깔끔하고 단순한 해법이 명백히 보인다면 그것을 입력하라
    • 만약 깔끔하고 단순한 해법이 있지만 구현하는 데 몇 분 정도 걸릴 것 같으면 일단 적어 놓은 뒤에 원래 문제로 돌아오자.
    • 빨리 초록 막대를 보는 것은 모든 죄를 사해준다. 하지만 아주 잠시 동안만이다.
  3. 올바르게 만든다.
    • 시스템이 작동하므로 직전에 저질렀던 죄악을 수습하자.
    • 좁고 올곧은 소프트웨어 정의의 길로 되돌아와서 중복을 제거하고 초록 막대로 되돌리자.

우리의 목적은

작동하는 깔끔한 코드를 얻는 것이다.

나같은 나부랭이 프로그래머에게는 너무너무 어렵지만 쉬운 말이다...

하지만 방법은 있다.

나누어서 정복하자(divide and conquer)

'작동하는' 이라는 부분을 먼저 해결하고
'깔끔한 코드' 부분을 해결하는 것이다.

$5 + 10 CHF = $10(환율이 2:1일 경우)
$5 X 2 = $10
amount를 private으로 만들기
Dollar 부작용(side effect)?
Money 반올림

앞서 살펴본 테스트를 통과했지만 뭔가 이상하다.

바로 Dollar에 대해 연산을 수행한 후에 해당 Dollar의 값이 바뀌는 점이다.

	@Test
    public void testMultiplication(){
        Dollar five = new Dollar(5);
        five.times(2);
        assertEquals(10, five.amount);
        five.times(3);
        assertEquals(15,five.amount);
    }

다시 공포의 빨간 막대...

그렇다면 times()에서 새로운 객체를 반환하게 하면 어떨까?
이렇게 되면 Dollar의 인터페이스를 수정해야 하고 그러기 위해서는 테스트도 수정해야 한다.


	@Test
    public void testMultiplication(){
        Dollar five = new Dollar(5);
        Dollar product = five.times(2);
        assertEquals(10, product.amount);
        product = five.times(3);
        assertEquals(15,product.amount);
    }

Dollar.times()를 아래와 같이 수정하면 그제서야 테스트가 돌아갈것이다.
근데 이제 NullpointException 을 곁들인

	public Dollar times(int multiplier) {
        this.amount *= multiplier;
        return null;
    }

자! 올바른 Dollar 객체를 반환시켜보자

	public Dollar times(int multiplier) {
        return new Dollar(amount * multiplier);
    }

$5 + 10 CHF = $10(환율이 2:1일 경우)
$5 X 2 = $10
amount를 private으로 만들기
Dollar 부작용(side effect)?
Money 반올림

드디어..

기분이 좋아졌다

일단 지금까지 배운것을 검토해보자.

  • 설계상 결함(Dollar 부작용)을 그 결함으로 인해 실패하는 테스트로 변환했다.
  • 스텁 구현으로 빠르게 컴파일을 통과하도록 만들었다.
  • 올바르다고 생각하는 코드를 입력하여 테스트를 통과했다.

일단 올바른 행위에 대해 결정을 내린 후에 그 행위를 얻어낼 수 있는 최상의 방법에 대해 이야기할 수 있다.

profile
늦었지만 꾸준히

0개의 댓글