디자인패턴

Decorator Pattern (데코레이터 패턴)

hik14 2022. 7. 25. 03:42

데코레이터 패턴

- 객체에 추가 요소를 동적으로 더할 수 있다

- 하위 클래스를 생성시 훨씬 유연하게 기능을 확장할 수 있다

기본적인 핵심기능이 고정되어 있고, 추가적인 옵션이 다양한 경우 

다양한 서브클래스가 발생할 수 있다.

 

 

기본 추상 클래스

object CoffeeBeans{
    val arabica = "Arabica"
    val robusta = "Robusta"
    val liberica = "Liberica"
}

abstract class Coffee (val beans: String = CoffeeBeans.arabica){

    var description = ""

    abstract fun getPrice(): Int
}

abstract class CondimentDecorator(private val coffee: Coffee): Coffee() {
    
    abstract fun getProductName(): String
}

실제 구현 클래스

 

Component Class

class Espresso(beans: String): Coffee(beans = beans){

    init {
        description = "에스프레소($beans)"
    }

    override fun getPrice(): Int {
        return 3000
    }
}

DecoClass

class Milk(private val coffee: Coffee) : CondimentDecorator(coffee){

    override fun getProductName(): String {
        description = coffee.description + ", Milk"
       return description
    }

    override fun getPrice(): Int {
        return coffee.getPrice() + 500
    }
}

class Choco(private val coffee: Coffee) :  CondimentDecorator(coffee){

    override fun getProductName(): String {
        description = coffee.description + ", Choco"
        return description
    }

    override fun getPrice(): Int {
        return coffee.getPrice() + 1000
    }
}

class Cinnamon(private val coffee: Coffee) :  CondimentDecorator(coffee){

    override fun getProductName(): String {
        description = coffee.description + ", Cinnamon"
        return description
    }

    override fun getPrice(): Int {
        return coffee.getPrice() + 400
    }
}

class Whipping(private val coffee: Coffee) :  CondimentDecorator(coffee){

    override fun getProductName(): String {
        description = coffee.description + ", whipping"
        return description
    }

    override fun getPrice(): Int {
        return coffee.getPrice()
    }
}

class Syrup(private val coffee: Coffee) :  CondimentDecorator(coffee){

    override fun getProductName(): String {
        description = coffee.description + ", Syrup"
        return description
    }

    override fun getPrice(): Int {
        return coffee.getPrice() + 100
    }
}

실행 및 결과

fun main() {

    val coffee = Espresso(CoffeeBeans.robusta)
    println(coffee.description)
    println(coffee.getPrice())


    val latte = Milk(coffee)
    println(latte.getProductName())
    println(latte.getPrice())

    val mocha1 = Choco(latte)
    println(mocha1.getProductName())
    println(mocha1.getPrice())

    val mocha2 = Whipping(mocha1)
    println(mocha2.getProductName())
    println(mocha2.getPrice())
}