Android 개발/Kotlin

Kotlin By 키워드에 대한 이해 # Property Delegate Pattern

Developer88 2022. 10. 11. 08:57
반응형

오늘은 Kotlin에서 많이 사용되는 by 키워드에 대해서 정리해 보려고 합니다.

by 키워드에 대해 알아보기 전에,

그 근간이 되는 Deletgate Pattern에 대해서 알아 보도록 하겠습니다.

 

1. Delegate Pattern 에 의한 Class Delegatation (클래스 위임)

Delegate 라는 의미는 위임한다는 뜻 입니다.

프로그래밍에서 자주 등장하는 용어이기도 한데요.

코드를 보면서 이해해 보도록 하겠습니다.

 

아래에는 같은 Car라는 인터페이스를 상속받는,

Tesla라는 클래스와 Kia라는 클래스가 있습니다.

Testla는 일반적인 클래스 이구요.

Kia는 Delegate패턴을 이용하였습니다.

 

 

 

Tesla클래스는 상속받은 인터페이스를 구현하였는데요.

Kia클래스는 상속받은 인터페이스를 구현은 하였는데,

스스로 한게 하나도 없습니다.

쉽게 말해서 객체를 생성하는 너가 다해라, 니거 가져다가 쓰겠다는 것 이지요.

너에게 위임한다는 의미입니다. 그래서 delegate이구요.

 

그런데 어짜피 이렇게 위임해서,

하는게 하나도 없는데 굳이 Kia클래스처럼 길게 쓸 필요가 없지 않을까요?

그래서 by키워드가 나왔습니다.

 

2. by키워드

위에서 본 것처럼, 한 마디로 "다 위임합니다. 알아서 하세요"라는 의미로 키워드 "by"를 사용하시면 되는데요.

위에서 보았던 4줄짜리 Kia클래스는 아래와 같이 한 줄로 표현할 수 있습니다.

사실 4줄짜리 Kia클래스도 Kotlin이라서 줄여서 쓴 것이지요, 원래는 더 길게 표현할 수도 있습니다.

 

 

이 클래스를 이용해 객체를 생성하려면,

Car를 상속받은 클래스를 이용해야 하겠지요.

여기서는 Tesla클래스를 이용하겠습니다.

 

 

3. Property Delegation ( Delegated Properties)

3-1. Property의 위임

Property도 위임(Delegate) 할 수 있는데요.

by키워드를 사용하면 Property가 위임된 delegate에 의해서 컨트롤된다는 의미로 해석할 수 있습니다.

 

delegated property는 아래와 같은 문법으로 사용하게 되는데요.

by키워드가 핵심입니다.

 

val/var <property name>: <Type> by <expression>

 

Observable 프로퍼티의 경우 많이 사용하게 되는데요.

Jetpack Compose를 사용해보셨다면, 아래와 같이 mutableStateOf라는 함수로 MutableState객체를 만들고,

by를 이용해서 아래와 같이 선언한 코드를 많이 보게됩니다.

 

 

By 키워드를 사용함으로서 컴파일시에 이 프로퍼티에 해당하는 get()이나 set() 함수는,

by에 의해서 위임된 expression의 getValue()와 setValue()함수로 delegate되기 때문입니다.

 

위에서 말한대로, MutableState 도 getValue()와 setValue()를 제공하고 있는지 볼까요?

네, 아래와 같은 형태로 제공해주고 있네요.

참고로 이렇게 제공하는 getValue()와 setValue()함수에는 operator 키워드를 붙여서 적혀져야 합니다.

 

 

 

제네릭 타입을 가지는 setValue()도 제공해 주고 있습니다.

 

 

위의 코드와 비슷한 문법으로 getValue와 setValue를 직접 작성해서 Delegated Property를 작성해서 사용할 수도 있습니다.

하지만, 이것의 의미를 알고 사용하는 것만으로도 많은 도움이 됩니다.

 

3-2. 코드작성의 편리함

by키워드를 사용함으로서, 코드작성을 편하게 해주는 면도 있는데요.

아래의 코드를 보도록 하겠습니다. 

아래는 by키워드를 사용하지 않은 상태입니다.

아래에 빨간줄로 컴파일에러가 나있는데 무슨일인지 보면, type이 MutableStateOf타입이어야 한다는 것 입니다.

getReceiptById는 Receipt타입이니까, MutableState타입으로 래핑되어야 한다 이것입니다.

 

 

그러니까 아래와 같이 한번 래핑을 하라는 것 이지요.

 

 

그런데, 아래와 같이 하지 않고 by키워들르 사용하면 쉽게 해결될 문제였습니다.

by키워드 사용하니 훨씬 간결하게아래와 같이 바뀝니다.

getter와 setter를 mutableStateOf()에 위임하니, 타입문제도 같이 해결되어버렸습니다.

receipt에 Int타입인 값을 "="으로 대입해준 순간 mutableStateOf<Receipt?>의 setter가 동작하게 된 것이지요.

 

 

Delegated Property를 사용하면 "by"키워드를 무심코 사용하기 보다는,

의미를 알아두고 잘 활용하면 많은 도움이 되는 것 같습니다.

 

이상으로 By키워드에 대해서 정리해 보았습니다.

 

728x90