Kotlin - Delegation

권태용·2020년 9월 26일
0

Kotlin

목록 보기
4/6

Q1. Kotlin에서 델리게이션은 뭔가요?

델리게이션은 뭘까요? 델리게이션이라는 단어 조차 처음들었다. 음 뭘까 하고 바로 구글링을 해봤지만 Delegation 패턴관련해서 나왔고 이해가 잘 되지 않았다.

우선 Kotlin 문서를 보고 하나하나 찾아가 보도록 하겠다.

Property Delegation

delegation의 공식문서를 찾아보면 https://kotlinlang.org/docs/reference/delegation.html Property Delegation 이 먼저 나온다.

There are certain common kinds of properties, that, though we can implement them manually every time we need them, would be very nice to implement once and for all, and put into a library. Examples include:

lazy properties: the value gets computed only upon first access;
observable properties: listeners get notified about changes to this property;
storing properties in a map, instead of a separate field for each property.

The syntax is: val/var : by . The expression after by is the delegate, because get() (and set()) corresponding to the property will be delegated to its getValue() and setValue() methods. Property delegates don’t have to implement any interface, but they have to provide a getValue() function (and setValue() — for vars). For example:

해석을 해보면 이렇다.

특정되는 공통 속성이 있다. 우리는 필요할때 그것을 매번 구현 할 수 있지만. 그런 속성을 모두 구현해서 라이브러리에 저장해두면 매우 좋을 것이다. 예를 들어

lazy properties: 값을 첫 번째 접근에서만 계산한다. + 해당 변수를 접근할때 최초 사용이 이루어질때까지 접근을 최대한 미룬다.
observalbe properties: 속성에 대한 값 변동 내역 알람
storing properties: 속성에 대해 별도의 필드 대신 map으로 저장
  
문법은 이렇다 val/var <property name> : <Type> by <expression>. by 뒤에 나오는 expression이 delegate이다. 이 property에 대한 get(),set() 메소드는 이 deletegate의 getValue()와 setValue() 메소드에 위임된다. 이 대리인은 인터페이스를 구현할 필요는 없지만 getValue와 setValue 함수를 제공해야 한다.

사용법은 위 문서를 읽어보는게 더 효과적이기에 설명은 생략하고 개념에 대해 더 생각해 보겠다.
속성에 대한 접근 로직을 사용자가 지정한 객체에 구현된 로직으로 변경 하는 것이다. 여기서 위임이라는 개념은 자신이 만들어 둔 기능을 어느 변수에나 적용할 수 있다는 장점이 있다.

그래서 Delegation 이란?

다시 돌아와서 Delegation이란 뭘까? 공식문서를 이어서 읽어보자

 The Delegation pattern has proven to be a good alternative to implementation inheritance, and Kotlin supports it natively requiring zero boilerplate code
 
 Delegation 패턴은 inheritance(상속) 구현 방식의 대안으로 입증 되었다. 그리고 Kotlin은 제로 biolerplate code를 지원한다. 

여기서 biolerplate code라는 것은 여러 군대서 재사용되는 반복적 코드를 의미한다.
그렇다면 delegation이 나온 이유는 궁극적으로 반복적인 코드를 없애기 위해 나왔다는 것이다.

목적을 이해 하였으니 실제 예시 코드를 살펴보자

interface Base {
  fun print()
}

class BaseImpl(val x: Int) : Base {
  override fun print() { print(x) }
}

class Derived(b: Base) : Base by b

fun main() {
  val b = BaseImpl(10)
  Derived(b).print()
}

The by-clause in the supertype list for Derived indicates that b will be stored internally in objects of Derived and the compiler will generate all the methods of Base that forward to b

by 절에 있는 Derived의 슈퍼타입 리스트는 b는 Derived 오브젝트에 저장되고 컴파일러는 Base의  모든 메소드를 b를 통해 만들어 낼 것이다.

위 코드가 의미하는 것은 Derived는 Base를 상속받을 것이고 Base의 메소드구현은 b에게 위임(Delegate) 한다는 것이다. 우선 Java의 Interface상속과 다른점은 상속 메소드의 구현을 굳이 상속클래스에서 구현하지 않아도 된다는 점이다.

내가 생각하기에 장점은

  1. 기존 Interface가 구현된 클래스를 상속받는다면 다중상속이 불가능하다. 하지만 위임을 사용한다면 가능하다. (인터페이스를 상속받고 위임을 통해 구현된 클래스를 넘겨줌)

  2. final class 상속이 가능하다.

  3. boilerplate code 가 줄어든다 인터페이스를 구현해 놓은 클래스가 있다면 해당 클래스를 위임자로 사용하면서 활용도가 증가한다.

    느낀점

Delegation을 구글링을 통해 이해하려 했어서 조금 힘들었다 하지만 Reference를 찾아보면서 예제 코드를 이해하는것이 큰 도움이 되었다. 내 나름 대로 정리를 하려하였지만 최고의 지침서는 공식문서 인거 같다.

profile
개발일기장

0개의 댓글