TDD 1.0 Help

9장. 우리가 사는 시간

할일 목록
  • $5 + 10CHF = $10 (환율이 2:1로 가정)

  • $5 x 2 = $10

  • amount를 private으로 만들기

  • Dollar side effect?

  • Money 반올림?

  • equals()

  • hashCode()

  • Equal null

  • Equal object

  • 5CHF x 2 = 10CHF

  • Dollar/Franc 중복

  • 공용 equals

  • 공용 times

  • Franc과 Dollar 비교하기

  • 통화?

  • testFrancMultiplication 제거

어떻게 하면 귀찮고 불필요한 하위 클래스를 제거할 수 있을까? 통화 개념을 도입해보면 어떨까?

통화 개념을 테스트할 수 있는 코드를 작성해보자.

@kotlin.test.Test fun testCurrency() { assertEquals("USD", Money.dollar(1).currency()) assertEquals("CHF", Money.franc(1).currency()) }

컴파일이 되게하기 위해서 Money에 currency() 메서드를 선언하고 두 하위 클래스에서 구현해보자.

abstract class Money(var amount: Int) { abstract fun currency(); } class Dollar(amount: Int) : Money(amount) { override fun currency(): String { return "USD" } } class Franc(amount: Int) : Money(amount) { override fun currency(): String { return "CHF" } }

우리는 두 클래스를 모두 포함할 수 있는 동일한 구혀늘 원하니 통화를 인스턴스 변수에 저장하고, 메서드에서는 그걸 반환하게 만들어보자.

class Dollar(amount: Int, private val currency: String = "USD") : Money(amount) { override fun currency(): String { return currency } } class Franc(amount: Int, private val currency: String = "CHF") : Money(amount) { override fun currency(): String { return currency } }

이제 두 currency() 구현이 동일하니 선언과 구현을 위로 올릴 수 있게 되었다.

abstract class Money(var amount: Int) { var currency: String? = null fun currency(): String? { return currency } }

생성자를 호출하는 곳의 컴파일 에러를 해결하자

abstract class Money(var amount: Int) { companion object { fun dollar(amount: Int): Money { return Dollar(amount, null) } fun franc(amount: Int): Money { return Franc(amount, null) } } } class Dollar(amount: Int, currency: String?) : Money(amount) { override fun times(multiplier: Int): Money { return Dollar(amount * multiplier, null) } } class Franc(amount: Int, currency: String?) : Money(amount) { override fun times(multiplier: Int): Money { return Franc(amount * multiplier, null) } }

times()메서드에서 객체 반환을 팩토리 메서드로 변경하자.

class Dollar(amount: Int, currency: String?) : Money(amount) { override fun times(multiplier: Int): Money { return dollar(amount * multiplier) } } class Franc(amount: Int, currency: String?) : Money(amount) { override fun times(multiplier: Int): Money { return franc(amount * multiplier) } }

이렇게 하면 팩토리 메서드에서도 통화단위를 전달할 수 있게된다.

fun dollar(amount: Int): Money { return Dollar(amount, "USD") } fun franc(amount: Int): Money { return Franc(amount, "CHF") }

Money의 생성자에 currency를 추가해주자.

abstract class Money(var amount: Int, var currency: String) { fun currency(): String { return currency } companion object { fun dollar(amount: Int): Money { return Dollar(amount, "USD") } fun franc(amount: Int): Money { return Franc(amount, "CHF") } } } class Dollar(amount: Int, currency: String) : Money(amount, currency) { } class Franc(amount: Int, currency: String) : Money(amount, currency) { }
할일 목록
  • $5 + 10CHF = $10 (환율이 2:1로 가정)

  • $5 x 2 = $10

  • amount를 private으로 만들기

  • Dollar side effect?

  • Money 반올림?

  • equals()

  • hashCode()

  • Equal null

  • Equal object

  • 5CHF x 2 = 10CHF

  • Dollar/Franc 중복

  • 공용 equals

  • 공용 times

  • Franc과 Dollar 비교하기

  • 통화?

  • testFrancMultiplication 제거

이제 times메서드를 상위 클래스로 올리고 하위 클래스를 제거할 준비가 거의 되었다.

Last modified: 31 January 2024