property delegate 를 사용하는것이 property delegation 이라고 부른다.
코틀린에서 lazy 함수 제공
1
val value by lazy { createValue() }
프로퍼티 위임을 사용하면 변화가 있을때 이를 감지하는 observable 패턴을 쉽게 만들수 있다.
1 2 3 4 5 6 7 8 9
var items: List<Item> by Delegates.observable(listOf()){ notifyDataSetChange } var key : String? by Delegates.observable(null){_,old,new-> Log.e("key changed from $old to $new") }
일반적으로 자바를 활용하면 어노테이션을 많이 사용해야 되지만 코틀린은 프로퍼티 위임을 사용해서 간단하고 type-safe 하게 구현 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 안드로이드에서의 뷰와 리소스 바인딩 privateval button: Button by bindView(R.id.button) privateval textSize by bindDimension(R.dimen.font_size) privateval doctor: Doctor by argExtra(DOCTOR_ARG)
// kotlin 에서의 종속성 주입 privateval presenter: MainPresenter by inject() privateval repository: NetworkRepository by inject() privateval vm: MainViewModel by viewModel()
// 데이터 바인딩 privateval port by bindConfiguration("port") privateval token: String by preferences.bind(TOKEN_KEY)
var token: String? = null get() { print("token returned value $field") return field } set(value) { print("token changed from $field to $value") field = value }
var attempts: Int = 0 get() { print("attempts returned value $field") return field } set(value) { print("attempts changed from $field to $value") field = value }
두개 프로퍼티 타입은 다르지만 내부적으로 거의 같은 처리를 한다. 그리고 프로젝트에서 자주 쓰일것 같다.
var token: String? by LoggingProperty(null) var attempts: Intby LoggingProperty(0)
privateclassLoggingProperty<T>(var value: T) { operatorfungetValue( thisRef: Any?, prop: KProperty<*> ): T { print("${prop.name} returned value $value") return value }
operatorfunsetValue( thisRef: Any?, prop: KPRoperty<*>, newValue: T ) { val name = prop.name print("name changed from $value to $newValue") value = newValue } }