1. 데코레이터 패턴?
- 데코레이터 패턴으로 객체에 추가 요소를 동적으로 더할 수 있는 패턴이다.
- 데코레이터를 사용하면 서브클래스를 만들 때보다 훨 씬 유연하게 기능을 확장할 수 있다.
[역할]
Component : 실질적인 인스턴스를 컨트롤하는 역할
ConcreteComponent : Component의 실질적인 인스턴스의 부분으로 책임의 주체의 역할
Decorator : Component와 ConcreteDecorator를 동일시 하도록 해주는 역할
ConcreteDecoreator : 실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체
2. 데코레이터 패턴의 장단점
장점
1. 기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장시킬 수 있다.
2. 구성과 위임을 통해서 실행중에 새로운 행동을 추가할 수 있다.
단점
1. 의미없는 객체들이 너무 많이 추가될 수 있다.
2. 데코레이터를 너무 많이 사용하면 코드가 필요 이상으로 복잡해질 수 있다.
3. 데코레이터를 이용한 주문시스템 클래스 구성도
- 제일 상단의 Beverage는 구성요소를 나타내는 Component 추상 클래스이다.
- HoustBlend, DarkRoast, Decaf, Espresso는 커피 종류마다의 구성요소를 나타내는 구상 클래스이다.
- Milk, Mocha, Soy, Whip은 각각의 첨가물을 나타내는 데코레이터이다.
4. 데코레이터를 사용해 주문시스템 구현
[추상 구성요소] Beverage
public abstract class Beverage {
String description = "제목 없음";
public String getDescription() {
return description;
}
public abstract double cost();
}
//Beverage 클래스를 확장
public abstract class CondimentDecorator extends Beverage {
Beverage beverage;
public abstract String getDescription();
}
- Beverage 객체가 들어갈 자리에 들어갈 수 있어야 한다. 따라서 Beverage 클래스를 확장한다.
- 모든 첨가물 데코레이터에서 getDescription() 메소드를 새로 구현하기 위해서 추상 메소드로 선언한다.
[구상 구성요소] Espresso, Decaf
public class Espresso extends Beverage {
public Espresso() {
description = "에스프레소";
}
public double cost() {
return 1.99;
}
}
public class Decaf extends Beverage {
public Espresso() {
description = "디카페인 커피";
}
public double cost() {
return 1.05;
}
}
[구상 데코레이터]
public class Mocha extends CondimentDecorator {
// 감싸고자 하는 객체를 받음
public Mocha(Beverage beverage) {
// 감싸고자 하는 음료를 저장
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", 모카";
}
public double cost() {
return beverage.cost() + .20;
}
}
- 데코레이터는 감싸고자하는 음료를 저장하기 위한 인스턴스가 필요하다.
[주문 테스트 코드]
public class StarbuzzCoffee {
public static void main(String args[]) {
Beverage beverage = new Espresso();
beverage = new Mocha(beverage); // Mocha로 감싼다
beverage = new Mocha(beverage); // Mocha로 감싼다
Beverage beverage2 = new Decaf();
beverage2 = new Whip(beverage2); // Whip으로 감싼다
System.out.println(beverage.getDescription() + " $" + beverage.cost());
// 에스프레소 커피, 모카, 모카 $1.99
System.out.println(beverage2.getDescription() + " $" + beverage.cost());
// 디카페인 커피, 휘핑크림 $2.49
}
}
'Design Pattern' 카테고리의 다른 글
[Design Pattern] 템플릿 메소드 패턴 (0) | 2023.03.05 |
---|---|
[Design Pattern] MVC패턴 (0) | 2023.01.09 |
[Design Patter] 상태패턴 (0) | 2023.01.07 |
[Design Pattern] 싱글톤 패턴 (0) | 2022.12.17 |