9장. 우리가 사는 시간
- 할일 목록
어떻게 하면 귀찮고 불필요한 하위 클래스를 제거할 수 있을까? 통화 개념을 도입해보면 어떨까?
통화 개념을 테스트할 수 있는 코드를 작성해보자.
@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) {
}
- 할일 목록
이제 times메서드를 상위 클래스로 올리고 하위 클래스를 제거할 준비가 거의 되었다.
Last modified: 31 January 2024