Programming/디자인 패턴

데코레이터 패턴(Decorator Pattern)

사랑우주인 2021. 12. 18. 20:25

데코레이터 패턴이란?

주어진 상황 및 용도에 따라 기본 객체에 책임(기능)을 동적으로 추가하는 패턴.

 

데코레이터의 예

스타벅스
기본 에스프레소에, 물, 우유, 시럽, 휘핑크림 등 개인의 선호에 따라 재료(기능)을 추가하면 다양한 음료를 재조할 수 있다. 이와 같이 하나의 객체(에스프레소)에 옵션들을 여러개 추가해서 만드는 패턴을 장식하는 것과 같다하여 데코레이터 패턴이라 한다. 

 

데코레이터 패턴 구조

 

데코레이터 코드

public class Main {

    public static void main(String[] args) {
        Component espresso = new BaseComponent();
        System.out.println("에스프레소 : " + espresso.add());
        
        Component americano = new WaterDecorator(new BaseComponent());
        System.out.println("아메리카노 : " + americano.add());
        
        Component latte = new MilkDecorator(new WaterDecorator(new BaseComponent()));
        System.out.println("라떼 : " + latte.add());
    }
}

 

<Component>

public interface Component {
    String add(); //재료 추가
}

실질적인 인스턴스를 컨트롤하는 역할

 

<ConcreteComponent>

public class BaseComponent implements Component {

    @Override
    public String add() {
        // TODO Auto-generated method stub
        return "에스프레소";
    }
}

Component의 실질적인 인스턴스의 부분으로 책임의 주체의 역할

 

<ConcreteDecoreator>

abstract public class Decorator implements Component {
    private Component coffeeComponent;
    
    public Decorator(Component coffeeComponent) {
        this.coffeeComponent = coffeeComponent;
    }
    
    public String add() {
        return coffeeComponent.add();
    }
}

Component와 ConcreteDecorator를 동일시 하도록 해주는 역할

 

//물을 추가해주는 클래스
public class WaterDecorator extends Decorator {
    public WaterDecorator(Component coffeeComponent) {
        super(coffeeComponent);
    }
    
    @Override
    public String add() {
        // TODO Auto-generated method stub
        return super.add() + " + 물";
    }
}

실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체

 

//우유를 추가해주는 클래스
public class MilkDecorator extends Decorator {
    public MilkDecorator(Component coffeeComponent) {
        super(coffeeComponent);
    }
    
    @Override
    public String add() {
        // TODO Auto-generated method stub
        return super.add() + " + 우유";
    }
}

실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체

 

데코레이터의 장단점

장점
1. 기본(중심) 객체를 수정하지 않고, 동적 추가 또는 삭제할 수 있다. 즉, OCP에 충실하다. 
2. 첨가 데이터가 일정하지 않고 다양할 때 효율적이다.
OCP(Open Close Principal)
확장에는 열려 있고, 변경에는 닫혀 있어야 한다. 

 

단점

데코레이터 클래스들이 계속해서 추가되면 코드가 복잡해질 수 있다.