본문 바로가기
디자인패턴

장식자 패턴 (Decorator Pattern)

by 이석준석이 2021. 7. 10.

사용 의도

  • 객체에 동적으로 새로운 책임을 추가할 수 있게 합니다.

참고

위의 글을 참고하여, 같은 예제를 따라해보고 복습해봅니다~!


예시

  • 위의 참고글에서 따온 아래와 같은 예시가 있다면
    • 카라멜 프라푸치노에, 헤이즐럽 시럽 한 번 넣고 자바칩 넣어주세요! 아 그리고 카라멜 드리즐이랑 초코 드리즐 깔아주시구요
  • 위의 메뉴에 대해 하나의 클래스를 만든다면, 모든 조합에 대해서 클래스를 만들어야하는, 매우 비정상적인 상황이 벌어집니다.

 

위의 경우처럼, 많은 조합에 대해서 다뤄야 하는 경우, Decorator Pattern 을 사용하는 것이 적절해보입니다.


Decorator Pattern

Decorator Pattern

참여자 설명
Component 동적으로 기능을 추가해야 할 가능성이 있는 객체들의 인터페이스
ConcreteComponent 추가적인 서비스가 실제적으로 정의되어야 할 필요가 있는 객체
Decorator Component 객체에 대한 참조를 관리하며 (has-A) Component 에 정의된 인터페이스를 만족하도록 인터페이스를 정의한다.
ConcreteDecorator Component 에 새롭게 추가할 서비스를 실제로 구현하는 클래스

 

구현했을 때, 클래스는 아래와 같습니다.

   
Component CoffeeComponent
ConcreteComponent Americano / Latte / Moca
Decorator CoffeeDecorator
ConcreteDecorator Drizzle / JavaChip / Cream


클래스

Component

public interface CoffeeComponent {
    long cost();
}

 

ConcreteComponent : 추가적인 서비스가 실제적으로 정의되어야 할 객체

public class Americano implements CoffeeComponent {
    @Override
    public long cost() {
        return 3000;
    }
}

public class Latte implements CoffeeComponent {
    @Override
    public long cost() {
        return 4000;
    }
}

 

Decorator : ConcreteComponent 와 has-A 관계를 만족하는 객체

@RequiredArgsConstructor
public class CoffeeDecorator implements CoffeeComponent {

    private final CoffeeComponent coffeeComponent;

    @Override
    public long cost() {
        return coffeeComponent.cost();
    }
}

 

ConcreteDecorator : 추가할 서비스들

public class Cream extends CoffeeDecorator {
    public Cream(CoffeeComponent coffeeComponent) {
        super(coffeeComponent);
    }

    @Override
    public long cost() {
        System.out.println("Cream ");
        return super.cost() + 500;
    }
}

public class Drizzle extends CoffeeDecorator {
    public Drizzle(CoffeeComponent coffeeComponent) {
        super(coffeeComponent);
    }

    @Override
    public long cost() {
        System.out.println("Drizzle ");
        return super.cost() + 400;
    }
}

 

사용

public class DecoratorClient {
    public static void main(String[] args) {
        final CoffeeComponent drizzle = new Cream(new Drizzle(new Americano()));
        System.out.println("cost = " + drizzle.cost()); // 3900원
    }
}