Design Pattern/구조 디자인 패턴

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

슝슝이입니다 2024. 4. 14. 00:09
반응형

 데코레이터 패턴은 객체에 추가적인 기능을 동적으로 첨부하는 디자인 패턴입니다. 이 패턴은 상속 대신에 구성을 사용하여 객체의 기능을 확장합니다. 기본 객체를 변경하지 않으면서 새로운 기능을 계속 추가할 수 있어 유연성을 제공합니다. 기본 객체에 하나 이상의 데코레이터를 "데코레이트"하여 기능을 추가할 수 있습니다.

1. 데코레이터 패턴은 주로 어디에 쓰이나?

데코레이터 패턴은 주로 UI 구성 요소 또는 스트림과 같은 객체에 동적으로 새로운 기능을 추가해야 할 때 사용됩니다. 예를 들어, Java의 I/O 클래스에서는 이 패턴을 사용하여 다양한 스트림(예: BufferedStream, DataInputStream)을 통해 추가적인 기능(버퍼링, 데이터 읽기 등)을 쉽게 첨가할 수 있습니다. 웹 개발에서도 HTTP 요청 객체에 기능을 추가하는 데 사용될 수 있습니다.

2. Java와 Go로 데코레이터 패턴을 구현할 때의 차이점

  • Java: Java에서는 추상 클래스 또는 인터페이스를 사용하여 데코레이터를 구현합니다. 각 데코레이터 클래스는 동일한 인터페이스를 구현하거나 같은 추상 클래스를 확장하고, 구성을 통해 객체에 기능을 추가합니다.
  • Go: Go에서는 인터페이스를 사용하여 데코레이터 패턴을 구현합니다. Go는 상속을 지원하지 않기 때문에, 인터페이스를 통해 다형성을 실현하고, 구조체를 사용하여 기능을 확장합니다.

3. 데코레이터 패턴 예시

Java 예시

interface Coffee {
    double getCost();
    String getDescription();
}

class SimpleCoffee implements Coffee {
    public double getCost() {
        return 1;
    }

    public String getDescription() {
        return "Simple coffee";
    }
}

class MilkDecorator extends SimpleCoffee {
    private Coffee coffee;

    public MilkDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    public double getCost() {
        return coffee.getCost() + 0.5;
    }

    public String getDescription() {
        return coffee.getDescription() + ", milk";
    }
}

// 사용 예
Coffee myCoffee = new MilkDecorator(new SimpleCoffee());
System.out.println(myCoffee.getDescription());  // 출력: Simple coffee, milk

 

Golang 예시

type Coffee interface {
    GetCost() float64
    GetDescription() string
}

type SimpleCoffee struct{}

func (s *SimpleCoffee) GetCost() float64 {
    return 1.0
}

func (s *SimpleCoffee) GetDescription() string {
    return "Simple coffee"
}

type MilkDecorator struct {
    Coffee Coffee
}

func (m *MilkDecorator) GetCost() float64 {
    return m.Coffee.GetCost() + 0.5
}

func (m *MilkDecorator) GetDescription() string {
    return m.Coffee.GetDescription() + ", milk"
}

// 사용 예
func main() {
    myCoffee := &MilkDecorator{Coffee: &SimpleCoffee{}}
    fmt.Println(myCoffee.GetDescription())  // 출력: Simple coffee, milk
}

4. 데코레이터 패턴의 장단점

장점:

  • 기존 코드를 수정하지 않고 새로운 기능을 추가할 수 있어, 시스템의 유연성을 증가시킵니다.
  • 다양한 조합의 기능을 쉽게 구성할 수 있습니다.
  • 단일 책임 원칙과 개방-폐쇄 원칙을 잘 지킬 수 있습니다.

단점:

  • 데코레이터를 많이 사용하면 시스템이 복잡해질 수 있으며, 코드를 추적하기 어려워질 수 있습니다.
  • 구성 요소 간의 의존성이 증가하여 버그가 발생할 가능성이 높아질 수 있습니다.

 

반응형