코틀린에서 많이 사용하는 by 키워드, 특히나 뷰모델을 사용할 때 많이 봤었습니다.
val viewModel: MainViewModel by viewModels()
단순히 viewModel을 위임하는 것이라고 알고 있었는데, 위임한다는 것이 무슨 의미이고, 어떤 식으로 작동하는지 알아보려고 합니다.
소프트웨어 엔지니어링에서 delegate pattern(위임 패턴)
은 객체 합성이 상속과 동일하게 코드 재사용을 할 수 있도록 하는 객체 지향 디자인 패턴이다.
https://en.wikipedia.org/wiki/Delegation_pattern
Delegate Pattern은 디자인 패턴 중 하나로, 한 객체가 다른 객체로부터 기능 일부를 넘겨받아 데이터를 제공하거나 특정 작업을 수행 할 수 있게 하는 것입니다.
객체지향에서는 상속을 허용하지 않는 클래스에 새로운 기능을 추가할 때 위임을 사용할 수 있습니다.
위임을 사용하면 상속하지 않고 기존 기능을 그대로 사용하면서 새로운 기능을 추가 할 수 있습니다.
Kotlin에서는 Delegate Pattern을 by
라는 키워드로 제공하고 있습니다.
이 by
라는 키워드는 Delegation을 직접 구현하는 데에서 생기는 보일러 플레이트 코드의 감소를 목적으로 사용됩니다.
interface Champion {
val hp: Int,
val mp: Int,
fun info()
}
League of Legend라는 게임을 예시로 들어서 설명해 보겠습니다.
Champion
이라는 인터페이스는 체력과 마나를 뜻하는 hp
, mp
, 체력과 마나 정보를 출력하는 info()
메서드를 가지고 있습니다.
class User(private val champ: Champion) : Champion {
override val hp: Int = champ.hp
override val mp: Int = champ.mp
override fun info() = champ.info()
}
User
라는 클래스는, Champion
을 직접 구현하는 것이 아닌, Champion
인터페이스의 구현체를 인자로 받아, 프로퍼티와 메서드를 위임 받고 있습니다
class Ezreal : Champion {
override val hp: Int = 500
override val mp: Int = 400
override fun info() {
print("체력은 $hp, 마나는 $mp 입니다.")
}
}
fun main(){
val user = User(Ezreal())
user.info()
}
자 그러면 이렇게 User
에 Champion
의 구현체인 Ezreal
을 전달하면, User
객체는 Ezreal
을 상속받지 않더라도 Ezreal
의 기능을 사용할 수 있습니다.
하지만, 프로퍼티가 많으면 많아질수록 위임하는 코드는 많아질 것이고, 이는 불필요한 코드를 야기할 것입니다.
이를 위해 코틀린에서 지원하는 키워드가 by 입니다.
class User(private val champ: Champion) : Champion by champ
Champ by champion
parameter로 들어온 champion
을 by
라는 키워드를 통해 위임해주면 이처럼 한줄로 해결할 수 있게 됩니다.
class User(private val champ: Champion) : Champion by champ {
override val hp = 300
}
fun main(){
val user = User(Ezreal())
user.info()
}
하지만, by 키워드를 사용하여 위임된 클래스에서 프로퍼티를 따로 설정해 두었을 때, delegate object인 user
는 이를 모르게 됩니다. 즉, hp 300은 출력되지 않게 됩니다.
코틀린의 기본 라이브러리는 open
되지 않은 final
클래스입니다.
코틀린에서는 표준 라이브러리의 무분별 상속을 지양합니다. 상속을 통해 클래스의 확장을 필요로 할 때가 있는데 위임을 사용하면 상속과 비슷하게 final
클래스의 모든 기능을 사용하면서, 동시에 기능을 확장할 수 있습니다.
다음 포스팅으로 이어집니다!
https://velog.io/@evergreen_tree/KotlinDelegation-2.-Delegated-Property
delegation... 델리게이션....델리만쥬...먹고싶다