Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

밤빵's 개발일지

[TIL]20241028 by 와 Delegation 본문

Kotlin

[TIL]20241028 by 와 Delegation

최밤빵 2024. 10. 28. 23:18

코틀린을 공부하면서 by 키워드위임 패턴(Delegation)이라는 새로운 개념을 알게 되었다. 위임 패턴은 객체지향 프로그래밍에서 자주 사용되는 디자인 패턴으로, 객체가 특정 기능을 다른 객체에게 위임(Delegation)하는 방식이다. 코틀린에서는 이 패턴을 지원하기 위해 by 키워드를 제공하며, 이를 사용하면 인터페이스 구현을 간결하고 효율적으로 처리할 수 있다. 이번 개발일지에서는 코틀린의 by 키워드를 활용한 위임 방법과 이로 인해 얻을 수 있는 장점을 정리해 보았다.

 

▶위임 패턴

위임 패턴(Delegation Pattern)은 객체가 특정 작업을 수행하기 위해 그 작업을 다른 객체에게 위임하는 디자인 패턴이다. 이 패턴을 사용하면 코드의 재사용성과 유연성이 높아지고, 복잡한 상속 구조를 피할 수 있다. 예를 들어, 클래스가 여러 기능을 제공해야 할 때 모든 기능을 직접 구현하지 않고, 해당 기능을 다른 객체에게 위임할 수 있다. 이를 통해 코드가 간결해지고 유지보수성이 향상된다.

 

▶ by 키워드를 사용한 위임

코틀린에서는 by 키워드를 사용하여 인터페이스 구현을 다른 객체에 위임할 수 있다. by 키워드는 클래스가 특정 인터페이스를 구현할 때, 그 구현을 다른 객체에게 위임하도록 도와준다. 이를 통해 반복적인 코드를 줄이고, 클래스 설계가 더욱 직관적으로 이루어진다.

▷예시: 인터페이스 위임

Printer라는 인터페이스를 PrinterDelegate 객체에 위임하는 방식으로 구현한 예시.

interface Printer {
    fun printMessage(message: String)
}

class ConsolePrinter : Printer {
    override fun printMessage(message: String) {
        println("Console Printer: $message")
    }
}

class PrinterDelegate(printer: Printer) : Printer by printer

fun main() {
    val consolePrinter = ConsolePrinter()
    val printerDelegate = PrinterDelegate(consolePrinter)

    printerDelegate.printMessage("Hello, Kotlin!")
}

Printer는 printMessage 메서드를 가진 인터페이스이다.

ConsolePrinter는 Printer 인터페이스를 구현한 클래스로, 여기서 printMessage 메서드는 콘솔에 메시지를 출력한다.

PrinterDelegate 클래스는 Printer by printer 구문을 사용해 Printer 인터페이스의 구현을 printer 객체에 위임한다.

→ main 함수에서 PrinterDelegate 객체를 생성하고, 메시지를 출력할 때 위임된 ConsolePrinter의 printMessage 메서드가 호출된다.

 

▶ by 키워드를 활용한 장점

 코드의 간결성

→ by 키워드를 사용하면 클래스가 인터페이스의 메서드를 하나하나 구현할 필요가 없어진다. 위 예시에서도 PrinterDelegate 클래스는 Printer 인터페이스의 모든 메서드를 by 키워드로 위임받아 구현했기 때문에, printMessage 메서드를 따로 정의할 필요가 없다.

유연한 코드 확장

→ 위임 패턴을 사용하면, 기능을 추가하거나 변경할 때 클래스 구조를 크게 수정하지 않아도 된다. 예를 들어, 위임받는 객체(printer)를 교체하는 것만으로 새로운 기능을 추가할 수 있다.

 다중 인터페이스 구현

→ by 키워드를 사용해 여러 인터페이스를 동시에 구현할 수 있다. 이를 통해 복잡한 상속 구조를 피하고, 코드의 재사용성을 극대화할 수 있다.

 

▶ by 키워드의 실전 예시: 로그 시스템

위임 패턴은 실전에서 다양한 용도로 사용될 수 있다. 예를 들어, 로그 시스템을 구현할 때 여러 출력 방식(Console, File 등)을 by 키워드를 활용해 손쉽게 전환할 수 있다.

▷예시: 로그 시스템 구현

interface Logger {
    fun log(message: String)
}

class ConsoleLogger : Logger {
    override fun log(message: String) {
        println("Console Log: $message")
    }
}

class FileLogger : Logger {
    override fun log(message: String) {
        // 파일에 로그를 기록하는 코드 (여기서는 단순 출력으로 대체)
        println("File Log: $message")
    }
}

class LogManager(logger: Logger) : Logger by logger

fun main() {
    val consoleLogger = ConsoleLogger()
    val fileLogger = FileLogger()

    val consoleLogManager = LogManager(consoleLogger)
    consoleLogManager.log("Logging to console.")

    val fileLogManager = LogManager(fileLogger)
    fileLogManager.log("Logging to file.")
}

Logger 인터페이스를 통해 로그 메시지를 기록할 수 있는 메서드 log를 정의.

ConsoleLoggerFileLogger는 각각 콘솔과 파일에 로그를 기록하는 구현체이다.

LogManagerLogger 인터페이스를 by 키워드를 사용해 위임받아 구현하고, 인자로 전달된 logger 객체에 따라 로그 기록 방식을 쉽게 변경할 수 있다.

 

▶ by 키워드와 상속의 차이점

by 키워드를 사용한 위임과 클래스를 상속받아 구현하는 방식에는 몇 가지 중요한 차이점이 있다.

항목 상속 (Inheritance) by 키워드 위임 (Delegation)
코드 재사용성 상속받은 부모 클래스의 모든 기능 사용 가능 특정 기능을 필요한 객체에 위임 가능
유지보수성 부모 클래스 변경 시, 자식 클래스에도 영향 위임 객체 교체만으로 기능 확장 가능
클래스 계층의 복잡성 복잡한 계층 구조를 형성할 수 있음 단일 클래스에서 여러 기능 위임 가능
유연성 특정 클래스에 종속적일 수 있음 동적으로 위임 객체를 교체 가능
코틀린의 by 키워드를 활용한 위임 패턴은 코드의 간결성과 유연성을 크게 향상시킬 수 있는 유용한 기능이다. 기존에 자바에서 사용했던 상속 개념과 달리, by 키워드는 불필요한 코드의 중복을 줄이고, 기능 확장을 더욱 쉽게 만들어준다. 

'Kotlin' 카테고리의 다른 글

[TIL]20241030 try-with-resources & use  (4) 2024.10.30
[TIL]20241029 Nested Functions  (3) 2024.10.29
[TIL]20241027 sealed class 와 Enum  (0) 2024.10.27
[TIL]20241026 apply, with, run  (2) 2024.10.26
[TIL]20241025 오버로딩 & 오버라이딩  (1) 2024.10.25