import ( "코딩", "행복", "즐거움" )

데코레이터 패턴(Decorator Pattern)?? 본문

소프트웨어 아키텍처

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

더코드마니아 2023. 2. 27. 17:51

데코레이터 패턴(Decorator Pattern)은 객체 지향 디자인 패턴 중 하나로, 객체에 동적으로 새로운 책임을 추가할 수 있도록 합니다. 이 패턴은 객체의 확장성과 유연성을 높여주며, 객체 간의 결합도를 낮출 수 있습니다.

 

데코레이터 패턴에서는 데코레이터(Decorator) 클래스와 컴포넌트(Component) 클래스가 있습니다.

 

컴포넌트 클래스는 인터페이스나 추상 클래스로 정의하며, 데코레이터 클래스는 컴포넌트 클래스와 같은 인터페이스를 구현하면서, 내부에 다른 컴포넌트 객체를 참조합니다.

 

데코레이터 클래스는 컴포넌트 객체를 감싸서, 컴포넌트가 제공하는 기능에 추가적인 기능을 동적으로 추가합니다.

 

이렇게 데코레이터 클래스를 계속해서 추가하면, 컴포넌트 객체에 여러 개의 기능을 쌓아올릴 수 있습니다. 데코레이터 클래스는 컴포넌트 객체에 대한 참조를 가지고 있으므로, 데코레이터 객체를 통해 컴포넌트 객체에 새로운 책임을 동적으로 추가할 수 있습니다.

 

이러한 데코레이터 패턴은 기존의 클래스를 수정하지 않고도, 객체의 기능을 확장할 수 있으므로, 객체의 재사용성과 유연성을 높여줍니다. 또한 데코레이터 클래스들은 서로 독립적으로 존재하므로, 객체 간의 결합도를 낮출 수 있습니다.

 


<코드예제>

package main

import "fmt"

// 컴포넌트 인터페이스 정의
type Component interface {
    Operation() string
}

// 구체적인 컴포넌트 구현체 정의
type ConcreteComponent struct{}

func (*ConcreteComponent) Operation() string {
    return "ConcreteComponent"
}

// 데코레이터 구현체 정의
type Decorator struct {
    component Component
}

func (d *Decorator) Operation() string {
    if d.component != nil {
        return d.component.Operation()
    }
    return ""
}

// 구체적인 데코레이터 구현체 정의
type ConcreteDecoratorA struct {
    Decorator
}

func (d *ConcreteDecoratorA) Operation() string {
    return "ConcreteDecoratorA(" + d.Decorator.Operation() + ")"
}

// 구체적인 데코레이터 구현체 정의
type ConcreteDecoratorB struct {
    Decorator
}

func (d *ConcreteDecoratorB) Operation() string {
    return "ConcreteDecoratorB(" + d.Decorator.Operation() + ")"
}

func main() {
    // 컴포넌트 생성
    component := &ConcreteComponent{}

    // 데코레이터 A 생성하여 컴포넌트를 감싸기
    decoratorA := &ConcreteDecoratorA{}
    decoratorA.component = component

    // 데코레이터 B 생성하여 데코레이터 A를 감싸기
    decoratorB := &ConcreteDecoratorB{}
    decoratorB.component = decoratorA

    // 데코레이터 B를 호출하여 실행 결과 출력
    fmt.Println(decoratorB.Operation())
}

위 코드는 Component 인터페이스를 정의하고, ConcreteComponent라는 구체적인 컴포넌트 구현체를 정의합니다.

Decorator 구조체를 정의하여 Operation() 메서드를 구현하고, component 필드로 다른 Component 인스턴스를 감싸게 됩니다.

 

ConcreteDecoratorA와 ConcreteDecoratorB 구조체는 Decorator 구조체를 감싸는 구체적인 데코레이터 구현체입니다. 이러한 구조체들은 Operation() 메서드를 오버라이드하여 원래 Decorator의 Operation() 메서드를 호출한 후에 새로운 동작을 추가합니다.

 

마지막으로 main() 함수에서 ConcreteComponent를 생성하고, ConcreteDecoratorA와 ConcreteDecoratorB로 감싸서 실행 결과를 출력합니다.