Skip to content

Instantly share code, notes, and snippets.

@eyedroot
Created August 13, 2019 06:02
Show Gist options
  • Select an option

  • Save eyedroot/a691d0636168e7328a6e92530d6933d9 to your computer and use it in GitHub Desktop.

Select an option

Save eyedroot/a691d0636168e7328a6e92530d6933d9 to your computer and use it in GitHub Desktop.
코틀린 프로퍼티 위임 (Delegated Property)
import kotlin.reflect.KProperty
/**
* 위임 프로퍼티란
*
* 프로퍼티 필드에 접근하는 접근자 로직을 다른 객체에 맡기는 방식을 말한다.
* 즉, 게터와 세터 메서드를 가지는 다른 객체를 만들어서 그 객채에 프로퍼티의 플드 접근로직을 위임하는 것.
*/
fun main(args: Array<String>) : Unit {
/**
* 예, Person이라는 클래스를 만들고 클래스의 프로퍼티 값이 변경되거나 읽어올 때마다 메세지를 발생시키는 기능을 넣고 싶다.
*/
class Person(val name: String, val _age: Int, val _salary: Int) {
var age: Int = _age
get() {
println("age get! $field")
return field
}
set(value) {
println("age set! $value")
field = value
}
var salary: Int = _salary
get() {
println("salary get! $field")
return field
}
set(value) {
println("salary set! $value")
field = value
}
}
val p = Person("임원빈", 29, 2000)
p.age = 30
p.salary = 3000
println("${p.name} - ${p.age} - ${p.salary}")
/**
* 뭔가 이상하지 이런식이라면 중복된 기능의 코드가 계속해서 증식할 것이다. 자바스크립트 처럼 callback 함수를 미리 1개 선언해 놓고
* 필요한 이벤트리스너의 함수를 할당해주는 것 처럼 코드를 수정하면 코틀린에서 추구하는 간결함을 한 껏 살릴 수 있지 않을까 하는데..
*/
class PropertyDelegator(val fname: String) {
var value: Int = 0
fun getMethod(): Int {
println("$fname get! $value")
return value
}
fun setMethod(newValue: Int) {
println("$fname set! $newValue")
value = newValue
}
}
class Person2(val name: String) {
val ageDelegator = PropertyDelegator("age")
val salaryDelegator = PropertyDelegator("salary")
var age: Int
get() = ageDelegator.getMethod()
set(value: Int) = ageDelegator.setMethod(value)
var salary: Int
get() = salaryDelegator.getMethod()
set(value: Int) = salaryDelegator.setMethod(value)
}
/**
* 이것도 뭔가 애매하다. PropertyDelegator 클래스를 따로 작성해줘야 하고..
* 여기서 사용할 수 있는게 바로 위임(Delegation)이다.
*/
class PropertyDelegator2(var value: Int) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
println("${property.name} get! $value")
return value
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: Int) {
value = newValue
}
}
class Person3(val name: String, age: Int, salary: Int) {
var age: Int by PropertyDelegator2(age)
var salary: Int by PropertyDelegator2(salary)
}
/**
* 위임 받을 클래스에는 getValue() 메서드와 setValue() 메서드가 구현되어 있어야 한다.
* getValue()와 setValue() 메서드의 앞에 operator 접근자가 붙어 있는 것에 유의하자.
*
* 또, getValue() 메서드와 setValue() 메서드는 지정된 파라미터를 사용해야 하며,
* 지정된 파라미터는 아래와 같다.
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment