코틀린은 프로퍼티 위임이라는 새로운 기능을 제공
- 프로퍼티 위임을 사용하면 일반적인 프로퍼티의 행위를 추출해서 재사용할 수 있다.
- 대표적으로 지연 프로퍼티인 lazy 프로퍼티가 존재
- 처음 사용하는 요청이 들어올 때 초기화 되는 프로퍼티
- val value by lazy { createValue() }
- 변화가 있을 때 이를 감지하는 observable 패턴, stdlib의 observable 델리게이트 기반으로 구현 가능
var items: List<Item> by
Delegates.observable(listOf()) { _, _, _ ->
notifyDataSetChanged()
}
var key: String? by
Delegates.observable(null) { _, old, new ->
Log.e("Key changed from new $old to $new")
}
프로퍼티 위임 메커니즘을 활용하면, 다양한 패턴들을 간단하고 type-safe하게 만들 수 있음
프로퍼티 위임을 통한 getter, setter 로깅
- 프로퍼티 위임은 다른 객체의 메소드를 활용해서 프로퍼티의 접근자(게터와 세터)를 만드는 방식
- 이때 다른 객체의 메소드 이름이 중요함
- 게터는 getValue, 세터는 setValue 함수를 사용해서 만들어야 한다.
- 객체를 만든 뒤에는 by 키워드를 사용해서, getVlaue와 setValue를 정의한 클래스와 연결해 주면 된다.
class LoggingProperty<T>(var value: T) {
operator fun getValue(
thisRef: Any?,
prop: KProperty<*>
): T {
println("${prop.name} returned vale $value")
return value
}
operator fun setValue(
thisRef: Any?,
prop: KProperty<*>,
newValue: T
) {
val name = prop.name
println("$name changed from $value to $newValue")
value = newValue
}
}
fun main() {
var tokenaaa: String? by LoggingProperty(null)
var attempts: Int by LoggingProperty(0)
tokenaaa
tokenaaa = "a"
attempts
attempts = 1
}
프로퍼티 위임이 어떻게 동작하는지 이해하려면, by가 어떻게 컴파일되는지 보는 것이 좋다. 위와 같은 코드는 아래와 비슷하게 컴파일된다.
@JvmField
private val 'token$delegate' =
LoggingProperty<String?>(null)
var token: String?
get() = 'token$delegate'.getValue(this, ::token)
set(value) {
'token$delegate'.setValue(this, ::token, value)
}
- 컨텍스트(this)와 프로퍼티 레퍼런스의 경계도 함께 사용하는 형태로 변경
- 컨텍스트를 활용하기 때문에 getValue와 setValue가 여러 개 있어도 문제가 없다. 상황에 따라서 적절한 메소드가 선택됨
- 위임 프로퍼티는 확장 함수로도 만들 수 있다.
코틀린 stdlib에서 알아 두면 좋은 프로퍼티 델리게이터
- lazy -> 지연 초기화
- Delegates.observable -> 프로퍼티의 데이터가 변할 때마다 callback을 받을 수 있다.
- Delegates.vetoable -> observable과 거의 유사하지만 반환 값이 있다
- Delgates.notNull -> 프로퍼티를 non-null 타입으로 변경
'Reading Record > 이펙티브 코틀린' 카테고리의 다른 글
[이펙티브 코틀린] Item23. 타입 파라미터의 섀도잉을 피하라 (0) | 2022.05.01 |
---|---|
[이펙티브 코틀린] Item22. 일반적인 알고리즘을 구현할 때 제네릭을 사용하라 (0) | 2022.05.01 |
[이펙티브 코틀린] Item20. 일반적인 알고리즘을 반복해서 구현하지 말라 (0) | 2022.05.01 |
[이펙티브 코틀린] Item19. knowledge를 반복하여 사용하지 말라 (0) | 2022.05.01 |
[이펙티브 코틀린] Item18. 코딩 컨벤션을 지켜라 (0) | 2022.04.26 |