PHpullh
학습 라이브러리/Kotlin/Delegation 패턴 — by, by lazy, observable

KOTLIN · 디자인패턴

Delegation 패턴 — by, by lazy, observable

Kotlin의 by 키워드는 위임 패턴을 언어 차원에서 지원합니다. 클래스 위임으로 상속 대신 구성을 쉽게 구현하고, 프로퍼티 위임으로 lazy, observable 등 반복 로직을 재사용할 수 있습니다.

디자인패턴중급delegationbylazyobservabledesign-pattern

핵심 설명

Kotlin의 by 키워드는 위임 패턴을 언어 차원에서 지원합니다. 클래스 위임으로 상속 대신 구성을 쉽게 구현하고, 프로퍼티 위임으로 lazy, observable 등 반복 로직을 재사용할 수 있습니다.

Kotlin code

import kotlin.properties.Delegates

// 1. 클래스 위임: 인터페이스 구현을 다른 객체에 위임
interface Printer {
    fun print(message: String)
}

class ConsolePrinter : Printer {
    override fun print(message: String) = println("[콘솔] $message")
}

// by 키워드로 Printer 구현을 ConsolePrinter에 위임
class LoggingPrinter(printer: Printer) : Printer by printer

// 2. 프로퍼티 위임
class UserSettings {
    // lazy: 최초 접근 시 한 번만 초기화
    val config: Map<String, String> by lazy {
        println("설정 로딩 중...")
        mapOf("theme" to "dark", "lang" to "ko")
    }

    // observable: 값 변경 시 콜백 실행
    var fontSize: Int by Delegates.observable(14) { _, old, new ->
        println("폰트 크기 변경: $old → $new")
    }

    // vetoable: 조건에 맞지 않으면 변경 거부
    var volume: Int by Delegates.vetoable(50) { _, _, new ->
        new in 0..100  // 0~100 범위만 허용
    }
}

fun main() {
    val printer = LoggingPrinter(ConsolePrinter())
    printer.print("위임 패턴 테스트")

    val settings = UserSettings()
    println(settings.config)       // lazy 초기화 발생
    println(settings.config)       // 캐시된 값 반환

    settings.fontSize = 18         // observable 콜백 실행
    settings.volume = 200          // vetoable: 거부됨
    println("볼륨: ${settings.volume}")  // 여전히 50
}

학습 팁

by lazy는 기본적으로 thread-safe(LazyThreadSafetyMode.SYNCHRONIZED)입니다. 단일 스레드 환경이면 lazy(LazyThreadSafetyMode.NONE)으로 성능을 높일 수 있습니다.

주의할 점

클래스 위임 시 위임 객체의 메서드를 오버라이드하면 위임 객체 내부에서 호출하는 다른 메서드는 여전히 원래 구현을 사용합니다. 위임은 상속과 다르게 다형성이 적용되지 않습니다.

자주 묻는 질문

Delegation 패턴 — by, by lazy, observable란 무엇인가요?

Kotlin의 by 키워드는 위임 패턴을 언어 차원에서 지원합니다. 클래스 위임으로 상속 대신 구성을 쉽게 구현하고, 프로퍼티 위임으로 lazy , observable 등 반복 로직을 재사용할 수 있습니다.

Delegation 패턴 — by, by lazy, observable 학습 시 주의할 점은 무엇인가요?

클래스 위임 시 위임 객체의 메서드를 오버라이드하면 위임 객체 내부에서 호출하는 다른 메서드는 여전히 원래 구현을 사용합니다. 위임은 상속과 다르게 다형성이 적용되지 않습니다.