< 현재 구현해야할 목록 >
간단하게 $5 + $5 = $10 부터 시작하자.
@Test
public void testSimpleAddition() {
Money sum = Money.dollar(5).plus(Money.dollar(5));
asserEquals(Money.dollar(10), sum);
}
// Money
class Money {
protected int amount;
protected String currency;
Money(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
public String toString() {
return amount + " " + currency;
}
Money times(int multiplier) {
return new Money(amount * multiplier, currency);
}
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && currency().equals(money.currency());
}
Money plus(Money addend) {
return new Money(amount + addend.amount, currency);
}
static Money dollar(int amount) {
return new Money(amount, "USD");
}
static Money franc(int amount) {
return new Money(amount, "CHF");
}
}
이 시스템의 어려운 제약은 다중 통화 사용에 대한 내용을 나머지 코드에서 숨기고 싶은 것이다.
Money와 비슷하게 동작하지만 사실은 두 Money의 합을 나타내는 객체를 만드는 것이 정답이다!
위의 내용에 맞춰 테스트 코드를 작성해보자.
@Test
public void testSimpleAddition() {
Money sum = Money.dollar(5).plus(Money.dollar(5));
assertEquals(Money.dollar(10), sum);
assertEquals(Money.dollar(10), reduced);
}
reduced란 이름은 Expression에 환율을 적용하는 것이다. 환율이 적용되는 곳은 은행이기 때문에 아래와 같이 추가할 수 있다.
@Test
public void testSimpleAddition() {
Money sum = Money.dollar(5).plus(Money.dollar(5));
assertEquals(Money.dollar(10), sum);
Money reduced = bank.reduce(sum, "USD");
assertEquals(Money.dollar(10), reduced);
}
이 테스트 코드에서 bank가 하는 일은 하나도 없다. 그저 객체만 있으면 된다.
@Test
public void testSimpleAddition() {
Money sum = Money.dollar(5).plus(Money.dollar(5));
assertEquals(Money.dollar(10), sum);
Bank bank = new Bank();
Money reduced = bank.reduce(sum, "USD");
assertEquals(Money.dollar(10), reduced);
}
두 Money의 합은 Expression이어야 한다.
@Test
public void testSimpleAddition() {
Money sum = Money.dollar(5).plus(Money.dollar(5));
assertEquals(Money.dollar(10), sum);
Money five = Money.dollar(5);
Expression sum = five.plus(five);
Bank bank = new Bank();
Money reduced = bank.reduce(sum, "USD");
assertEquals(Money.dollar(10), reduced);
}
이를 컴파일하기 위해서는 Expression 인터페이스가 필요하다 (class도 가능하지만 인터페이스가 더 가볍다.)
public interface Expression {
}
Money.plus()는 Expression을 반환해야 한다.
class Money implements Expression {
Expression plus(Money addend) {
return new Money(amount + addend.amount, currency);
}
}
빈 Bank 객체 class를 만들고, reduce()를 생성한다.
public class Bank {
Money reduce(Expression source, String to) {
return Money.dollar(10);
}
}
우리는