본문 바로가기

CS/DesignPattern

(DesignPattern) 데코레이터 패턴

데코레이터 패턴이란 무엇이고 왜 쓰는가?

동적, 책임 추가

 

객체의 결합을 통해 기능을 동적으로 확장할 수 있게 만들어주는 패턴

 

기본 기능에 여러 가지 추가할 수 있는 기능의 종류가 많은 경우에 각 추가 기능을 Decorator 클래스로 정의한 뒤 필요한 Decorator 객체를 조합함으로써 추가 기능의 조합을 설계하는 방식이다.

 

 

  • Component(interface) - 실질적인 인스턴스를 컨트롤하는 역할
  • ConcreteComponent - Component의 실질적인 인스턴스 부분이며 책임의 주체 역할
  • Decorator - Component와 ConcreteDecorator를 동일 시 하도록 해주는 역할
  • ConcreteDecorator - 실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체 부분


실습

요구사항

커피를 제조하고 총가격을 구해보자!

 

처음 샷 추가 시 +100원
두 번째 샷 추가 시 30% 할인된  +70원

우유 추가 시 +50원

Component 인터페이스

public interface IBeverage {
	
	int getTotalPrice();

}

ConcreteComponent - 실질적인 구현 클래스

public class Base implements IBeverage{

	@Override
	public int getTotalPrice() {
		// TODO Auto-generated method stub
		return 0;
	}

}

Decorator - Component 간접 참조

public abstract class AbstAdding implements IBeverage{
	
	IBeverage iBeverage;

	public AbstAdding(IBeverage iBeverage) {
		super();
		this.iBeverage = iBeverage;
	}

	@Override
	public int getTotalPrice() {
		// TODO Auto-generated method stub
		return iBeverage.getTotalPrice();
	}

}

ConcreteDecorator

public class Milk extends AbstAdding{

	public Milk(IBeverage iBeverage) {
		super(iBeverage);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int getTotalPrice() {
		// TODO Auto-generated method stub
		return super.getTotalPrice()+50;
	}
}
public class Espresso extends AbstAdding{
	
	static protected int espressoCnt = 0;

	public Espresso(IBeverage iBeverage) {
		super(iBeverage);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int getTotalPrice() {
		// TODO Auto-generated method stub
		return super.getTotalPrice()+getAddPrice();
	}
	
	private static int getAddPrice() {
		espressoCnt += 1;	
		int addPrice = 100;
		
		if(espressoCnt > 1) {
			addPrice = 70;
		}
		
		return addPrice;
	}
}

Main

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		
		IBeverage beverage = new Base();
		boolean done = false;
		
		
		while(!done) {
			System.out.println("음료 현재 가격 :: "+beverage.getTotalPrice());
			System.out.println("선택 : 1 - 샷 추가  /  2 - 우유추가");
			
			switch (sc.nextInt()) {
			case 0: done = true;			
				break;
				
			case 1: 
				beverage = new Espresso(beverage);			
				break;
				
			case 2: 
				beverage = new Milk(beverage);		
				break;
			}
		}
		
		System.out.println("음료가격 :: "+beverage.getTotalPrice());
		sc.close();
	
	}
}

References

https://gmlwjd9405.github.io/2018/07/09/decorator-pattern.html

 

[Design Pattern] 데코레이터 패턴이란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io