|

Kotlin context parameters는 무엇을 바꾸려는 걸까: receiver와 DI 사이에서 이해하기

Kotlin context parameters는 무엇을 바꾸려는 걸까: receiver와 DI 사이에서 이해하기
Kotlin context parameters는 호출 문맥에 필요한 값을 더 명시적으로 표현하려는 기능이다.

Kotlin context parameters는 처음 보면 DI를 대체하는 기능처럼 보이기도 하고, receiver 문법의 확장처럼 보이기도 합니다. 하지만 핵심은 조금 다릅니다.

이 글에서는 함수가 실행되기 위해 필요한 문맥 값을 타입 수준에서 요구하는 방식으로 context parameters를 이해해 보겠습니다. Kotlin 공식 문서의 context parameters 문서를 기준으로 설명합니다.


Kotlin context parameters 이해 기준

Kotlin context parameters 이해 기준 카드
context parameters는 숨은 전역 상태가 아니라 호출 문맥을 타입으로 표현하려는 방향이다.

context parameters는 무엇을 표현하려는 걸까

어떤 함수는 단순한 인자만으로는 충분하지 않습니다. 로그 기록기, 설정, 권한, 트랜잭션, formatter처럼 호출 문맥에 이미 있어야 하는 값이 필요할 때가 있습니다. context parameters는 이런 문맥 의존성을 함수 시그니처에 드러내려는 방향입니다.

context(logger: Logger)
fun User.activate() {
    logger.info("activate user: $id")
}

이 예시는 개념을 보여주기 위한 단순 코드입니다. 함수가 Logger라는 문맥을 필요로 한다는 사실을 숨기지 않고 선언부에 드러냅니다.

receiver와 무엇이 다를까

Kotlin의 extension function과 receiver는 특정 객체를 중심으로 함수를 자연스럽게 확장할 수 있게 해줍니다. scope function과 receiver 차이는 코틀린 let, run, apply, also, with 차이에서도 자주 헷갈리는 부분입니다. receiver 하나에 너무 많은 의미를 담으면, 이 함수가 실제로 어떤 주변 문맥을 필요로 하는지 흐려질 수 있습니다.

context parameters는 주 receiver와 별도로 필요한 문맥 값을 표현할 수 있습니다. 그래서 DSL이나 도메인 코드에서 “이 블록 안에서만 가능한 작업”을 타입으로 제한하는 데 도움이 될 수 있습니다.

DI 컨테이너를 대체하는 기능일까

context parameters는 DI 컨테이너를 통째로 대체하는 기능으로 보는 것보다, 함수가 필요한 문맥을 더 명시적으로 요구하는 언어 기능으로 보는 편이 안전합니다. 객체 생성, 생명주기, 스코프 관리, 모듈 바인딩까지 모두 해결해 주는 것은 아닙니다.

  • 작은 문맥 의존성은 context parameters로 표현할 수 있다.
  • 앱 전체 객체 생명주기 관리는 여전히 DI 프레임워크가 필요할 수 있다.
  • 숨은 전역 상태처럼 남용하면 오히려 추적이 어려워진다.
  • 실험적 기능이면 팀의 Kotlin 버전과 빌드 설정을 먼저 확인해야 한다.

언제 쓸 만할까

context parameters는 여러 함수가 같은 문맥을 공유하고, 그 문맥이 없으면 호출 자체가 성립하지 않는 경우에 어울립니다. 예를 들어 HTML DSL, transaction scope, authorization scope, formatting scope 같은 영역을 생각할 수 있습니다.

context(tx: Transaction)
fun Order.pay() {
    tx.record("pay order: $id")
    status = OrderStatus.PAID
}

이런 코드는 함수가 transaction 문맥 밖에서 호출되면 안 된다는 의도를 드러냅니다. 다만 실제 프로덕션 코드에서는 예외 처리, 테스트, IDE 지원, 팀 합의까지 함께 봐야 합니다.

주의할 점

  • 새로운 문법이라 팀원이 읽기 어려울 수 있다.
  • 명시적 인자가 더 단순한 경우에는 굳이 쓰지 않는다.
  • 테스트에서 context 값을 어떻게 제공할지 미리 정한다.
  • 여러 context가 겹치면 오히려 숨은 의존성이 늘 수 있다.
  • 공식 문서의 지원 상태와 Kotlin 버전을 확인한다.

정리

Kotlin context parameters는 receiver와 DI 사이 어딘가의 마법 같은 기능이 아닙니다. 함수가 필요한 문맥 값을 타입 수준에서 드러내려는 문법입니다. 작은 DSL과 scope 표현에는 도움이 될 수 있지만, 앱 전체 의존성 관리나 객체 생명주기 문제까지 대신 해결해 주지는 않습니다.

함께보면 좋은 글