내용 보기

작성자

관리자 (IP : 172.17.0.1)

날짜

2020-07-09 07:25

제목

[Kotlin] 코틀린 기초 10 - 델리게이션


  • 델리게이션

델리게이션은 어떠한 행위를 위임자에게 맡기는 개념이다. 이러한 델리게이션 패턴을
코틀린에서는 쉽게 구현하기 위해 by키워드를 제공한다.

// By키워드를 사용한 델리게이션 패턴 작성

class MyDelegatee {
    fun print(str: String) {
        println("i am delegatee : $str");
    }
}
 
class MyDelegator {
    val delegatee: MyDelegatee = MyDelegatee();
    fun print(str: String) {
        delegatee.print(str);
    }
}
val obj: MyDelegator = MyDelegator();
obj.print("test test");
cs

실행결과
i am delegatee : test test

위 코드를 by를 이용하여 다음처럼 작성 할 수 있다.

interface IPrint {
    fun print(arg: String);
}
 
class MyDelegatee : IPrint {
    override fun print(arg: String) {
        println("i am delegatee : $arg");
    }
}
 
class MyDelegator(obj: MyDelegatee) : IPrint by obj

val obj: MyDelegatee = MyDelegatee();
MyDelegator(obj).print("hello test")
cs

실행 결과
i am delegatee : hello test

  • 델리게이션 프로퍼티

by를 이용해 클래스 위임을 대행하는 것과 같은 개념으로 프로퍼티의 위임도 제공한다.
만약 프로퍼티의 get(), set()메서드에 들어가는 로직이 여러 프로퍼티에
중복된다면, 중복되는 로직을 구현하는 클래스를 만들어 처리를 위임할 수 있다.

// 프로퍼티 by

class Test {
    private var _sum: Int = 0;
    private var _sum2: Int = 0;
 
    var sum: Int
        get() = _sum;
        set(value) {
            _sum = 0;
            for(i in 1..value) {
                _sum += i;
            }
        }
 
    var sum2: Int
        get() = _sum2;
        set(value) {
            _sum2 = 0;
            for(i in 1..value) {
                _sum2 += i;
            }
        }
}
 
val obj: Test = Test();
obj.sum = 10;
obj.sum2 = 5;
 
println(obj.sum);
println(obj.sum2);
cs

위 코드를 보면 프로퍼티의 set의 로직이 중복된다. 이럴 때 위임 프로퍼티를 이용하면 중복코드를 줄일 수 있다.

import kotlin.reflect.KProperty;
 
class MySumDelegate {
    private var _result: Int = 0;
 
    operator fun getValue(refVal: Any?, property: KProperty<*>): Int {
        println("getValue call.. ref : $refVal, property : ${property.name}");
        return _result;
    }
 
    operator fun setValue(refVal: Any?, property: KProperty<*>, value: Int) {
        _result = 0;
        println("setValue call.. value : $value, ${property.name}");
 
        for(i in 1..value) {
            _result += i;
        }
    }
}
 
class Test {
    var sum: Int by MySumDelegate();
    var sum2: Int by MySumDelegate();
}
 
val obj: Test = Test();
obj.sum = 10;
obj.sum2 = 5;
 
println(obj.sum);
println(obj.sum2);
cs

MySumDelegate 클래스가 여러 프로퍼티에 공통으로 사용되는 로직을 담는 클래스이다.
이 처럼 프로퍼티를 대행할 클래스를 만들려면 getValue()와 setValue()메서드를 포함해야 한다.

getValue()와 setValue()는 리플렉션을 통한 프로퍼티 정보를 가져오는 KProperty 인터페이스 파라메터와
각 get, set에 맞는 파라메터를 정의해서 사용할 수 있다.

출처1

출처2