일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- javascript
- it
- jsp
- redis
- AWS
- php
- Oracle
- 맛집
- JVM
- ReactJS
- elasticsearch
- Spring Boot
- Spring
- Git
- springboot
- jenkins
- tool
- IntelliJ
- java
- db
- Gradle
- ubuntu
- MySQL
- Spring Batch
- Web Server
- 요리
- linux
- devops
- Design Patterns
- laravel
Archives
- Today
- Total
아무거나
[Design Pattern] Decorator Pattern 본문
반응형
데코레이터 패턴(Decorator Pattern)
동적
으로 책임 추가
가 필요할 때 사용한다.
Component: 실질적인 인스턴스를 컨트롤하는 역할 즉, decorator와 Component를을 컨트롤 하는 역할이다.
(method 부분이 책임 부분) ConcreteComponent: Component의 실질적인 인스턴스의 부분이며, 책임의 주체의 역할 즉, Component가 컨트롤하는 객체
Decorator: Component와 concrete decorator를 동일시 하도록 해주는 역할 즉, Decorator은 Component가 될 수 있고, Component들을 가지고 있는 모양세를 가지고 있다고 생각하면 된다.
ConcreteDecorator: 실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체 부분이다. (addedMethod는 Concrete Decorator에서 사용할 Method를 추가하는 부분)
데코레이터 패턴 예시 - 1
[요구사항]
-
커피제조
- 에스프레스: 커피의 기본
- 아메리카노: 에스프레소 + 물
- 카페라떼: 에스프레스 + 스팀밀크
- 헤이즐넛: 아메리카노 + 헤이즐넛 시럽
- 카페모카: 카페라떼 + 초콜릿
- 캬라멜 마끼야또: 카페라떼 + 캬라멜 시럽
-
UML
- IBeverage: 커피의 가격을 산출하는 인터페이스
- Base: 실질적으로 책임져야할 부분 즉, 가격이 축적이됨을 Base에서 계속 가지고 있음
- AbstAdding: 추가 재료들을 구현
- Espresso: 재료
IBeverage 인터페이스를 생성하고 총 가격에 대한 책임을 묻는 getTotalPrice 메서드를 생성하자.
[IBeverage.java]
package com.bkjeon.decorator;
/**
* <li>에스프레스: 커피의 기본</li>
* <li>아메리카노: 에스프레소 + 물</li>
* <li>카페라떼: 에스프레스 + 스팀밀크</li>
* <li>헤이즐넛: 아메리카노 + 헤이즐넛 시럽</li>
* <li>카페모카: 카페라떼 + 초콜릿</li>
* <li>캬라멜 마끼야또: 카페라떼 + 캬라멜 시럽</li>
*
* @author bongkeun jeon
*/
public interface IBeverage {
/**
* 총 가격
*/
int getTotalPrice();
}
Component의 실질적인 인스턴스의 부분이며, 책임의 주체인 Base 클래스를 구현하자.
[Base.java]
package com.bkjeon.decorator;
/**
* <h2><b>Role: </b>ConcreteComponent</h2>
* <p>
* Component의 실질적인 인스턴스의 부분이며, 책임의 주체이다.
* </p>
* @author bongkeun jeon
*/
public class Base implements IBeverage {
@Override
public int getTotalPrice() {
return 0;
}
}
Decorator를 구현하자. [AbstAdding.java]
package com.bkjeon.decorator;
/**
* <h2><b>Role: </b>Decorator</h2>
* <p>
* 컴포넌트와 장식을 동일시 해주는 역할을 한다.
* </p>
* @author bongkeun jeon
*/
abstract public class AbstAdding implements IBeverage {
private IBeverage base;
public AbstAdding(IBeverage base) {
super();
this.base = base;
}
@Override
public int getTotalPrice() {
return base.getTotalPrice();
}
protected IBeverage getBase() {
return base;
}
}
ConcreteDecorator를 만들자. (Espresso.java, Milk.java)
[Milk.java]
package com.bkjeon.decorator;
/**
* <h2><b>Role: </b>ConcreteDecorator</h2>
* <p>
* 실질적인 장식 인스턴스 및 정의이며, 책임이 추가되는 부분이다.
* </p>
* @author bongkeun jeon
*/
public class Milk extends AbstAdding {
public Milk(IBeverage meterial) {
super(meterial);
}
@Override
public int getTotalPrice() {
return super.getTotalPrice() + 50;
}
}
[Espresso.java]
package com.bkjeon.decorator;
/**
* <h2><b>Role: </b>ConcreteDecorator</h2>
* <p>
* 실질적인 장식 인스턴스 및 정의이며, 책임이 추가되는 부분이다.
* </p>
* @author bongkeun jeon
*/
public class Espresso extends AbstAdding {
static protected int espressoCount = 0;
public Espresso(IBeverage base) {
super(base);
}
@Override
public int getTotalPrice() {
return super.getTotalPrice() + getAddPrice();
}
/**
* 에스프레소 추가가격
* 에스프레소 원샷: +100, 에스프레소 투샷: +70 (할인)
* @return
*/
private static int getAddPrice() {
espressoCount += 1;
int addPrice = 100;
if (espressoCount > 1) {
addPrice = 70;
}
return addPrice;
}
}
메인 클래스를 작성하자.
[Main.java]
package com.bkjeon.decorator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// base
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();
}
}
실행결과
음료 현재 가격: 0
선택: 1:샷 추가 / 2:우유 추가
1
음료 현재 가격: 100
선택: 1:샷 추가 / 2:우유 추가
1
음료 현재 가격: 140
선택: 1:샷 추가 / 2:우유 추가
2
음료 현재 가격: 190
선택: 1:샷 추가 / 2:우유 추가
2
음료 현재 가격: 240
선택: 1:샷 추가 / 2:우유 추가
0
음료 가격: 240
반응형
'Java & Kotlin > Java' 카테고리의 다른 글
[Design Pattern] Chain of Responsibility Pattern (0) | 2020.01.04 |
---|---|
[Design Pattern] Visitor Pattern (0) | 2020.01.01 |
yyyy-MM-dd 형태의 날짜 조회 방법 (0) | 2019.12.26 |
<![CDATA[ ]]> 사용 이유 (0) | 2019.12.24 |
[Design Pattern] Composite Pattern (0) | 2019.12.21 |
Comments