CS/디자인패턴

[디자인 패턴][구조 패턴] - 데코레이터 패턴

흰무 2023. 7. 12. 10:20

1. 데코레이터 패턴

객체의 기능을 런타임 시에 동적으로 추가하거나 수정할 수 있게 해주는 패턴
기본 객체에 추가적인 기능을 덧붙이는 방식으로 동작하며, 객체 간의 계층 구조를 가짐
  • 사용하는 경우
    • 객체의 기능을 확장하고자 할 때: 기존 객체를 변경하지 않고 새로운 기능을 추가하거나 수정
    • 기능의 조합이 많은 경우: 다양한 기능 조합이 필요한 경우, 각각의 기능을 개별적으로 구현하여 조합
  • 구현 방법

 

데코레이터 패턴 UML 다이어그램

  • Componen 인터페이스 : 기본 객체와 데코레이터 객체가 구현하는 공통 인터페이스, 기본 객체나 데코레이터 객체 모두 이 인터페이스를 구현
  • ConcreteComponent 클래스: 기본 객체를 나타내는 클래스로, 기본 기능을 구현
  • Decorator : 데코레이터 객체의 공통 기능을 정의하는 추상 클래스 또는 인터페이스
  • ConcreteDecorator 클래스 : 실제로 기능을 추가하거나 수정하는 데코레이터 클래스, Decorator 클래스를 상속하며 추가 기능을 구현

 

  • 예시
// Component 인터페이스
public interface Coffee {
    String getDescription();
    double getCost();
}

// ConcreteComponent 클래스
public class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double getCost() {
        return 1.0;
    }
}

// Decorator 추상 클래스
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

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

    @Override
    public String getDescription() {
        return coffee.getDescription();
    }

    @Override
    public double getCost() {
        return coffee.getCost();
    }
}

// ConcreteDecorator 클래스
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", Milk";
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.5;
    }
}

// ConcreteDecorator 클래스
public class WhipDecorator extends CoffeeDecorator {
    public WhipDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", Whip";
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.7;
    }
}

// 테스트
public class Main {
    public static void main(String[] args) {
        Coffee simpleCoffee = new SimpleCoffee();
        System.out.println(simpleCoffee.getDescription() + " - Cost: $" + simpleCoffee.getCost());

        Coffee coffeeWithMilk = new MilkDecorator(simpleCoffee);
        System.out.println(coffeeWithMilk.getDescription() + " - Cost: $" + coffeeWithMilk.getCost());

        Coffee coffeeWithMilkAndWhip = new WhipDecorator(coffeeWithMilk);
        System.out.println(coffeeWithMilkAndWhip.getDescription() + " - Cost: $" + coffeeWithMilkAndWhip.getCost());
    }
}

 

ConcreteComponent 클래스를 기반으로, 다른 Decorator 클래스들을 추가해서 사용할 수 있다.