[kotlin] 코틀린에서 상속과 인터페이스를 활용한 디자인 패턴 예제

개요

디자인 패턴은 소프트웨어 개발에서 일반적으로 발생하는 문제를 해결하기 위한 프로블림 및 솔루션 사이의 정형화된 방법입니다. Kotlin은 객체지향 언어로서 디자인 패턴을 적용하기에 적합한 기능을 제공합니다. 이 글에서는 Kotlin에서 상속과 인터페이스를 활용하여 유명한 디자인 패턴 중 몇 가지를 구현하는 예제를 살펴보겠습니다.

1. Singleton 패턴

Singleton 패턴은 애플리케이션에서 하나의 인스턴스만을 유지하고, 전역적으로 접근 가능한 방법을 제공하는 패턴입니다.

object Singleton {
    fun showMessage() {
        println("Singleton 패턴 예제입니다.")
    }
}

fun main() {
    Singleton.showMessage()
}

2. Observer 패턴

Observer 패턴은 객체 간의 일대다 의존 관계에서 일어나는 상태 변화를 관찰할 수 있는 패턴입니다.

interface Observer {
    fun update(message: String)
}

class Subject {
    private val observers = mutableListOf<Observer>()

    fun attach(observer: Observer) {
        observers.add(observer)
    }

    fun detach(observer: Observer) {
        observers.remove(observer)
    }

    fun notify(message: String) {
        for (observer in observers) {
            observer.update(message)
        }
    }
}

class ConcreteObserver(private val name: String) : Observer {
    override fun update(message: String) {
        println("$name이(가) 업데이트를 받음: $message")
    }
}

fun main() {
    val subject = Subject()
    val observer1 = ConcreteObserver("Observer1")
    val observer2 = ConcreteObserver("Observer2")

    subject.attach(observer1)
    subject.attach(observer2)

    subject.notify("새로운 메시지가 도착했습니다.")
}

3. Strategy 패턴

Strategy 패턴은 알고리즘을 캡슐화하여 동적으로 변경할 수 있는 패턴입니다.

interface Strategy {
    fun execute(a: Int, b: Int): Int
}

class AddStrategy : Strategy {
    override fun execute(a: Int, b: Int): Int {
        return a + b
    }
}

class MultiplyStrategy : Strategy {
    override fun execute(a: Int, b: Int): Int {
        return a * b
    }
}

class Context(private val strategy: Strategy) {
    fun executeStrategy(a: Int, b: Int): Int {
        return strategy.execute(a, b)
    }
}

fun main() {
    val addStrategy = AddStrategy()
    val context1 = Context(addStrategy)
    println("Add 결과: ${context1.executeStrategy(3, 5)}")

    val multiplyStrategy = MultiplyStrategy()
    val context2 = Context(multiplyStrategy)
    println("Multiply 결과: ${context2.executeStrategy(3, 5)}")
}

결론

Kotlin은 객체지향 언어로서 상속과 인터페이스를 활용하여 다양한 디자인 패턴을 적용할 수 있습니다. Singleton, Observer, Strategy와 같은 유명한 디자인 패턴은 Kotlin에서도 유용하게 활용할 수 있으며, 이를 통해 소프트웨어의 구조를 유연하게 설계할 수 있습니다.

참고 자료