코틀린 (Kotlin) by - by the way, what is this?

JoJo Develog·2020년 3월 24일
4

Kotlin

목록 보기
2/2
post-thumbnail

Illustration by Virginia Poltrack

코틀린은 다양한 키워드 및 연산자를 지원하며 Hard Keywords, Soft Keywords, Modifier Keywords, Operators로 공식 코틀린 문서에 분류하여 소개되어있습니다.

그중에서 Soft Keywords의 하나인 by에 대해 정리해보려고 합니다.

1. 'by' the way, What is this? 🤔

출처 : https://kotlinlang.org/docs/reference/keyword-reference.html#soft-keywords

코틀린 레퍼런스 항목에 "by"는 위의 이미지 처럼 소개되어 있습니다.

  • by
    • Interface 구현을 다른 객체에 위임
    • Property의 Accessor 구현을 다른 객체에 위임

위의 소개 글을 읽어보면 "by" 키워드는 클래스 또는 프로퍼티를 위임할 때 사용하는 키워드라고 알수 있습니다.

일단 먼저 위임이라는 것이 무엇인지 짚어보고 가겠습니다.

  1. 위임(delegation)이란?
  • 위탁자(delegator) → 수탁자(delegate) 형태이며 어떤 일의 책임 및 처리를 다른 클래스 또는 메서드에게 넘긴다는 의미.
  • 한 객체가 기능 일부를 다른 객체로 넘겨주어, 첫 번째 객체 대신 수행하도록 하는 일.
  • 다른 클래스의 기능을 사용하되 그 기능을 변경하지 않으려면 상속 대신 위임.
  • 위임을 활용하면 한 객체의 변경이 다른 객체에 미치는 영향이 작아짐.

❖ 출처 제타위키

그러면 이러한 위임(delegation)을 왜 사용해야 하는 걸까요??

2. Why use it? 🤨

객체지향 언어로 프로그램을 개발하다 보면 하위 클래스가 상위 클래스를 상속해서 상위 클래스의 메서드를 오버라이드를 하는 경우가 많습니다.
이런 오버 라이딩 상황에서 프로그램 유지보수를 하다 보면 상위 클래스가 내용이 변경이 되는 경우 하위 클래스가 상위 클래스에 의존 및 참조하고 있던 상황이 변경되면서 하위 클래스에 뜻하지 않은 에러가 발생합니다.

대표적인 상속의 문제점은 아래와 같습니다.

  • 상위 클래스와 하위 클래스의 서로 간의 결합도가 높아져 상위 클래스의 변화가 하위 클래스에 주는 영향을 예측하기 어렵다.
  • 불필요한 상위 클래스의 메서드까지 구현해야 한다.
  • final클래스의 경우 상속이 불가능하다.
  • 상속 구조가 복잡해질수록 그 영향에 대한 예측이 힘들어진다.
  • 하위 클래스로 내려갈수록 기능이 더해져 파악하기 어렵다.

그래서 코틀린에서는 자바와는 달리 상속으로 인한 종속성, 의존성 문제를 방지하기 위해 기본적으로 클래스는 final 입니다.
만약 상속을 원한다면 상속될 클래스에 open 접근자를 명시해야 상위 클래스의 내용 변경 시 의존하고 있는 하위 클래스에 영향을 줄 수 있다는 것을 인지시켜 줄 수 있습니다.

이러한 종속성, 의존성 문제를 해결할 때 ☝️Delegation pattern(위임 패턴)은 상속의 좋은 대안으로 증명이 되었는데 Kotlin에서는 언어 자체에서 이러한 위임 패턴을 지원합니다.

☝️Delegation pattern (위임 패턴)
소프트웨어 엔지니어링에서 위임 패턴은 객체 구성에서 상속과 동일한 코드 재사용을 가능하게 해주는 객체지향 디자인 패턴입니다.

3. For "Delegation" 😎

상속의 대안 "위임(Delegation)"
상속을 허용하지 않는 클래스에 새로운 기능을 추가할 때는 위임을 사용하며 사용 시 상속하지 않고 기존 기능을 그대로 사용하면서 새로운 기능을 추가할 수 있습니다.

즉, 쉽게 설명하면 하나의 클래스를 다른 클래스에 위임하도록 위임 선언을 하고 위임된 클래스가 가지는 인터페이스 메서드를 별도의 참조 없이 호출할 수 있도록 생성해주는 기능입니다.

이러한 위임을 코틀린에서는 "by" 키워드를 사용하여 위임 기능을 사용할 수 있습니다.
또한 코틀린은 중복 코드 없는 위임 패턴을 지원합니다.

다음은 코틀린 레퍼런스 예제 코드입니다.

interface Base {
    fun print()
}

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

/*Derived 클래스는 Base 인터페이스를 상속할 수 있으며, 
모든 public 메서드를 지정한 객체로 위임한다.*/
class Derived(b: Base) : Base by b

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

실행시 출력 값
10

Derived 클래스에 있는 "by" 절은 Derived 클래스의 객체 내부에 b 를 저장한다는 것을 의미하며 컴파일러는 Base의 모든 메서드를 b 로 전달하도록 Derived 클래스를 생성합니다.
다만, override는 그대로 동작합니다.
override가 존재하면 컴파일러는 위임 객체의 메서드 대신 override 구현을 사용합니다.
Derived에 override fun print() { print("abc") } 를 추가하면 프로그램은 "10" 대신 "abc"를 출력한다.

정리하면 코틀린에서도 마찬가지로 위임이란 아래와 같습니다.

  • 특정 처리를 다른 객체에게 넘기는 것을 의미함.
  • 다른 객체는 클래스 내부(포함)에 가지고 있음.
  • 코틀린에서는 "by" 키워드로 클래스 위임을 사용 가능.

이러한 Delegation에도 장단점이 존재합니다.

  • 상속은 단 하나의 Super Class(부모 클래스)만 가능하지만 위임은 복수의 interface가 가능합니다.
  • ptotected method/properties는 사용 불가능합니다.
  • interface 정의가 필요합니다.
  • 코드가 유연 해지지만 관련 지식이 없으면 이해하기가 어려워집니다.
  • 상속은 객체의 크기에 따라 증가시키는 비용이 발생합니다.

Reference

https://zerogdev.blogspot.com/2019/06/kotlin-by.html
https://medium.com/til-kotlin-ko/kotlin의-클래스-위임은-어떻게-동작하는가-c14dcbbb08ad <- 도창욱님 블로그, 강력 추천합니다.👍👍👍👍👍
https://kotlinlang.org/docs/reference/delegation.html

도서 참조
Kotlin in Action (드미트리 제메로프, 스베트라나 이사코바 저/오현석 역)
GoF의 디자인 패턴 (에릭 감마 저 / 김정아 역)

포스팅된 글에 잘못된 내용이 있을시 피드백 주시면 수정하겠습니다.

profile
12년도부터 대학에서 안드로이드 모바일을 전공으로 시작하여 "진짜 개발자"를 꿈꾸며 개발공부를 시작했습니다. SW 개발이 재밌어서 여러 방면으로 스터디하며 현재는 새로운 환경 및 새로운 트렌드에도 유연하게 적응을 잘하는 개발자로 성장해 나가는 중입니다. 글 내용에 대한 피드백은 언제나 환영입니다!

1개의 댓글

comment-user-thumbnail
2022년 1월 14일

정리 감사합니다!

답글 달기