1부 14장 바꾸기

이제 달러가 아닌 프랑을 이야기해보자.

아래와 같이 간단한 테스트를 작성할 수 있다.

 @Test
    public void testReduceMoneyDifferentCurrency() {
        Bank bank = new Bank();
        bank.addRate("CHF", "USD", 2);
        Money result = bank.reduce(Money.franc(2), "USD");
        assertEquals(Money.dollar(1), result);
    }

Money에서 프랑을 달러로 변환할 때 단순히 나누기 2를 하는 코드를 작성한다.

public Money reduce(String to) {
        int rate = (currency.equals("CHF") && to.equals("USD"))
                ? 2
                : 1;
        return new Money(amount / rate, to);
    }

Money가 환율을 어떻게 계산하는지 알게 됐다. 참 별로인 코드다. 하지만 우선 작성하자.

이제 Bank에서 환율을 계산할 수 있게 되었다.

// Bank
public class Bank {
    Money reduce(Expression source, String to) {
       return source.reduce(to);
    }

    int rate(String from, String to) {
        return (from.equals("CHF") && to.equals("USD"))
                ? 2
                : 1;
    }
}

// Money
public Money reduce(Bank bank, String to) {
        int rate = bank.rate(currency, to);
        return new Money(amount / rate, to);
    }

이렇게해도 테스트는 실패하기 때문에 키를 위한 객체를 따로 만들어보자.

public class Pair {
    private String from;
    private String to;

    public Pair(String from, String to) {
        this.from = from;
        this.to = to;
    }
}

Pair를 키로 쓸 거니까 equals(), hashCode()를 구현해야 한다.

public class Pair {
    private String from;
    private String to;

    public Pair(String from, String to) {
        this.from = from;
        this.to = to;
    }
    
    public boolean equals(Object object) {
        Pair pair = (Pair) object;
        return from.equals(pair.from) && to.equals(pair.to);
    }
    
    public int hashCode() {
        return 0;
    }
}

0은 최악의 해쉬코드지만 진행한다.

일단 환율을 저장할 뭔가가 필요하다. 또한 환율을 설정할 수도 있어야 한다. 마지막으로 필요할 때 환율을 걷어낼 수도 있어야 한다.

public class Bank {
    private Hashtable rates = new Hashtable();

    Money reduce(Expression source, String to) {
       return source.reduce(to);
    }

    int rate(String from, String to) {
        if (from.equals(to)) {
            return 1;
        }
        Integer rate = (Integer) rates.get(new Pair(from, to));
        return rate.intValue();
    }
    
    void addRate(String from, String to, int rate ) {
        rates.put(new Pair(from, to), new Integer(rate));
    }
}

테스트를 통과한다!

우리는 지금까지

  • 필요할거라고 생각한 인자를 추가했다.
  • 코드와 테스트 사이에 있는 데이터 중복을 끄집어냈다.
  • 자바의 오퍼레이션에 대한 가정을 검사해보기 위한 테스트를(testArray-Equals) 작성했다.
  • 별도의 테스트 없이 전용(private) 도우미(helper) 클래스를 만들었다.
  • 리팩토링하다가 실수를 했고, 그 문제를 분리하기 위해 또 하나의 테스트를 작성해서 계속 전진했다.

좋은 웹페이지 즐겨찾기