데코레이터 패턴이란 무엇이고 왜 쓰는가?
동적, 책임 추가
객체의 결합을 통해 기능을 동적으로 확장할 수 있게 만들어주는 패턴
기본 기능에 여러 가지 추가할 수 있는 기능의 종류가 많은 경우에 각 추가 기능을 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
'CS > DesignPattern' 카테고리의 다른 글
(DesignPattern) 책임사슬 패턴 (0) | 2020.05.30 |
---|---|
(DesignPattern) 방문자 패턴 (0) | 2020.05.30 |
(DesignPattern) 컴포짓 패턴 (0) | 2020.05.29 |
(DesignPattern) 브릿지 패턴 (0) | 2020.05.17 |
(DesignPattern) 추상팩토리 메서드 패턴 (0) | 2020.05.16 |