본문 바로가기

디자인패턴

[디자인패턴] 데코레이터 패턴 (Decorator Pattern)

데코레이터 패턴 (Decorator Pattern) 이란

기본 기능 외에도 여러가지 추가 기능들이 있을 때, 다양한 조합을 동적으로  구현할 수  있는 패턴이다.

GoF 디자인 패턴 분류에 따르면, 클래스/객체를 조합하여 더 큰 구조를 만드는 구조 패턴 (Structural Pattern) 의 한 종류로 분류가 된다.

 

UML 은 아래와 같이 구성이 된다.

decorator pattern

 

단순 상속을 하는 방법도 사용이 될 수 있겠지만, 그럴 경우 여러가지 조합을 가진 클래스를 구성 할때에 가지수가 굉장히 많아지게 되는 문제가 생긴다.


 

의자를 Decorator Pattern을 통해 만드는 예제로 데코레이터 패턴을 이해해보려고 한다.

 

아무 특색이 없는 기본 기능만을 가진  의자  OrdinaryChiar 클래스는 Component 에 해당하는 Chair 클래스를 상속받으며, Concrete Component 에 해당된다.

abstract class Chair { // Component
    abstract fun make()
}
/**
 * 단순하고 특색 없는 기본 의자.
 */
class OrdinaryChair : Chair() { // Concrete Component

    override fun make() {
        println("의자")
    }
}

 

의자의 다양한 구체적 기능들(Concrete Decorator ) 은 Decorator 에 해당하는 ChairDecorator 를 상속받아 구현을 한다. 

/**
 * 추가 기능들의 공통 부모 클래스.
 */
open class ChairDecorator(var decoratedChair: Chair) : Chair() { // Decorator
    override fun make() {
        decoratedChair.make()
    }
}
/**
 * 등받이 만들어 붙여주는 데코레이터.
 */
class BackRestDecorator(decoratedChair: Chair) : ChairDecorator(decoratedChair) {
    override fun make() {
        super.make()
        makeBackRest()
    }
    private fun makeBackRest() {
        println("등받이 부착")
    }
}

/**
 * 팔걸이를 만들어 붙여주는 데코레이터.
 */
class ArmsetDecorator(decoratedChair: Chair) : ChairDecorator(decoratedChair) {
    override fun make() {
        super.make()
        makeArmset()
    }
    private fun makeArmset() {
        println("팔걸이 부착")
    }
}


/**
 * 바퀴 만들어 붙여주는 데코레이터.
 */
class WheelDecorator(decoratedChair: Chair) : ChairDecorator(decoratedChair) {
    override fun make() {
        super.make()
        makeWheel()
    }
    private fun makeWheel() {
        println("바퀴 부착")
    }
}

 

이때 주목할  점은 Decorator 클래스가 Component 로 컴포지션 관계를 갖는다는 것이다.

 

따라서,

1) 구체적 기능들에 해당하는 클래스들  (Concrete Decorator) 에서 기본 기능 클래스 (Concrete Component) 에 대한 참조가 가능하며,

2) 어떤 기능이 추가 되던지, Client 는  Component  클래스만을 통해서 동일한 방법으로 객체를 사용할 수 있다.

 

 

아래와 같이 Client 에서 사용할 수 있으며, 실행결과는 아래와 같다.

@Test
fun testDecoratorPattern() {
    val customMadeChair: Chair = BackRestDecorator(
        WheelDecorator(ArmsetDecorator(OrdinaryChair()))
    )
    customMadeChair.make()
}

실행결과

의자
팔걸이 부착
바퀴 부착
등받이 부착

'디자인패턴' 카테고리의 다른 글

[디자인패턴] 스테이트 패턴 (State Pattern)  (0) 2020.03.15
SOLID 원칙  (0) 2019.05.06