본문으둜 κ±΄λ„ˆλ›°κΈ°

🌈 Chapter 16: λ“œλ””μ–΄, 좔상화

λ‹€μŒμ€ Sum.plus()에 λŒ€ν•œ ν…ŒμŠ€νŠΈλ‹€.

public void testSumPlusMoney() {
Expression fiveBucks = Money.dollar(5);
Expression tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Expression sum = new Sum(fiveBucks, tenFrancs).plus(fiveBucks);
Money result = bank.reduce(sum, "USD");
assertEquals(Money.dollar(15), result);
}

fiveBucks와 tenFrancsλ₯Ό λ”ν•΄μ„œ Sum을 생성할 μˆ˜λ„ μžˆμ§€λ§Œ μœ„μ˜ μ½”λ“œμ—μ„œλŠ” λͺ…μ‹œμ μœΌλ‘œ Sum을 μƒμ„±ν•˜λŠ”λ°, 이게 더 μ§μ ‘μ μœΌλ‘œ 우리 μ˜λ„λ₯Ό λ“œλŸ¬λ‚Έλ‹€. μš°λ¦¬κ°€ 이 ν…ŒμŠ€νŠΈλ“€μ„ μž‘μ„±ν•˜λŠ” 것은 단지 μžμ‹ μ˜ ν”„λ‘œκ·Έλž˜λ° κ²½ν—˜μ„ 더 재미있고 보람차게 ν•˜λ €κ³  ν•˜λŠ” κ²ƒλ§Œμ΄ μ•„λ‹ˆκ³ , ν›„λŒ€κ°€ 우리의 μ²œμž¬μ„±μ„ 감상할 수 μžˆλŠ” λ‘œμ œνƒ€μ„μ΄ λ˜λ„λ‘ ν•˜κΈ° μœ„ν•¨μ΄κΈ°λ„ ν•˜λ‹€.
ν…ŒμŠ€νŠΈκ°€ μ½”λ“œλ³΄λ‹€ 더 κΈΈλ‹€. 그리고 μ½”λ“œλŠ” Money의 μ½”λ“œμ™€ λ˜‘κ°™λ‹€.

// Sum
public Expression plus(Expression addend) {
return new Sum(this, addend);
}

TDD둜 κ΅¬ν˜„ν•  땐 ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ 쀄 μˆ˜μ™€ λͺ¨λΈ μ½”λ“œμ˜ 쀄 μˆ˜κ°€ 거의 λΉ„μŠ·ν•œ μƒνƒœλ‘œ λλ‚œλ‹€. TDDκ°€ 경제적이기 μœ„ν•΄μ„œλŠ” 맀일 λ§Œλ“€μ–΄ λ‚΄λŠ” μ½”λ“œμ˜ 쀄 μˆ˜κ°€ 두 λ°°κ°€ λ˜κ±°λ‚˜ λ™μΌν•œ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜λ˜ 절반의 쀄 수둜 ν•΄λ‚΄μ•Ό ν•  것이닀. TDDκ°€ μžμ‹ μ˜ 방법에 λΉ„ν•΄ μ–΄λ–»κ²Œ λ‹€λ₯Έμ§€ 직접 μΈ‘μ •ν•΄ 보아야 ν•  것이닀. μ΄λ•Œ 디버깅, 톡합 μž‘μ—…, λ‹€λ₯Έ μ‚¬λžŒμ—κ²Œ μ„€λͺ…ν•˜λŠ” 데 κ±Έλ¦¬λŠ” μ‹œκ°„ λ“±μ˜ μš”μ†Œλ₯Ό λ°˜λ“œμ‹œ 포함해야 ν•œλ‹€λŠ” 것을 κΈ°μ–΅ν•˜κΈ° λ°”λž€λ‹€.

일단 Sum.times()κ°€ μž‘λ™ν•˜κ²Œ λ§Œλ“€ 수만 μžˆλ‹€λ©΄ Expression.times()λ₯Ό μ„ μ–Έν•˜λŠ” 일이야 어렡지 μ•Šμ„ 것이닀. ν…ŒμŠ€νŠΈλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

public void testSumTimes() {
Expression fiveBucks = Money.dollar(5);
Expression tenFrancs = Money.franc(10);
Bank bank = new Bank();
bank.addRate("CHF", "USD", 2);
Expression sum = new Sum(fiveBucks, tenFrancs).plus(2);
Money result = bank.reduce(sum, "USD");
assertEquals(Money.dollar(20), result);
}

μ΄λ²ˆμ—λ„ ν…ŒμŠ€νŠΈκ°€ μ½”λ“œλ³΄λ‹€ κΈΈλ‹€.

// Sum
Expression times(int multiplier) {
return new Sum(augend.times(multiplier), addend.times(multiplier));
}

μ§€λ‚œ μž₯μ—μ„œ ν”Όκ°€μ‚°μˆ˜(augend)와 기수(addend)λ₯Ό Expression으둜 μΆ”μƒν™”ν–ˆκΈ° λ•Œλ¬Έμ— μ½”λ“œκ°€ 컴파일되게 λ§Œλ“€λ €λ©΄ Expression에 times()λ₯Ό μ„ μ–Έν•΄μ•Ό ν•œλ‹€.

// Expression
Expression times(int multiplier);

이 μž‘μ—… 떄문에 Money.times()와 Sum.times()의 κ°€μ‹œμ„±μ„ λ†’μ—¬μ€˜μ•Ό ν•œλ‹€.

// Sum
public Expression times(int multiplier) {
return new Sum(augend.times(multiplier), addend.times(multiplier));
}

// Money
public Expression times(int multiplier) {
return new Money(amount * multiplier, currency);
}

ν…ŒμŠ€νŠΈκ°€ ν†΅κ³Όν•œλ‹€.
λ­”κ°€ κΉ”λ”νžˆ 정리해야 ν•  것이 μžˆλ‹€λ©΄, $5 + $5λ₯Ό ν•  λ•Œμ— Moneyλ₯Ό λ°˜ν™˜ν•˜λŠ” κ±Έ μ‹€ν—˜ν•΄ λ³΄λŠ” 것이닀. ν…ŒμŠ€νŠΈλŠ” λ‹€μŒκ³Ό 같을 것이닀.

public void testPlusSameCurrencyReturnMoney() {
Expression sum = Money.dollar(1).plus(Money.dollar(1));
assertTrue(sum instanceof Money);
}

이 ν…ŒμŠ€νŠΈλŠ” 외뢀에 λ“œλŸ¬λ‚˜λŠ” 객체의 ν–‰μœ„μ— λŒ€ν•œ 것이 μ•„λ‹ˆλΌ κ΅¬ν˜„ 쀑심이기 떄문에 μ’€ μ§€μ €λΆ„ν•˜λ‹€. κ·Έλ ‡κΈ°λŠ” ν•˜μ§€λ§Œ 이 ν…ŒμŠ€νŠΈλŠ” μš°λ¦¬κ°€ μ›ν•˜λŠ” λ³€ν™”λ₯Ό κ°€ν•  수 있게 ν•΄μ€€λ‹€. κ²Œλ‹€κ°€ 이 ν…ŒμŠ€νŠΈλŠ” 단지 μ‹€ν—˜μΌ 뿐이닀. 이 ν…ŒμŠ€νŠΈλ₯Ό ν†΅κ³Όμ‹œν‚€κΈ° μœ„ν•΄ λ‹€μŒκ³Ό 같이 μ“Έ 수 μžˆλ‹€.

// Money
public Expression plus(Expression addend) {
return new Sum(this, addend);
}

μΈμžκ°€ Money일 κ²½μš°μ—, 그리고 μ˜€λ‘œμ§€ κ·Έ κ²½μš°μ—λ§Œ 인자의 톡화λ₯Ό ν™•μΈν•˜λŠ” λΆ„λͺ…ν•˜κ³ λ„ κΉ”λ”ν•œ 방법이 μ—†λ‹€. μ‹€ν—˜μ€ μ‹€νŒ¨ν–ˆκ³ , 우린 ν…ŒμŠ€νŠΈλ₯Ό μ‚­μ œν•˜κ³ (μ–΄μ°¨ν”Ό λ³„λ‘œ μ•ˆ μ’‹κ²Œ μƒκ°ν•˜λ˜ ν…ŒμŠ€νŠΈμ˜€λ‹€) λ– λ‚œλ‹€.