데코레이터 패턴은 기존 객체에 추가적인 기능을 동적으로 부여할 수 있도록 설계하는 구조적(Structural) 디자인 패턴입니다.
이를 통해 클래스를 수정하지 않고도 객체의 기능을 확장할 수 있습니다.
Component를 확장하며, 추가적인 기능을 정의할 수 있도록 하는 추상 클래스// 1. Component 인터페이스 정의
interface Coffee {
String getDescription();
double cost();
}
// 2. ConcreteComponent (구체적인 기본 클래스)
class BasicCoffee implements Coffee {
@Override
public String getDescription() {
return "기본 커피";
}
@Override
public double cost() {
return 3000;
}
}
// 3. Decorator (데코레이터 추상 클래스)
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee; // 기존 커피 객체를 감싸기 위한 변수
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public double cost() {
return coffee.cost();
}
}
// 4. ConcreteDecorator (구체적인 데코레이터: 우유 추가)
class Milk extends CoffeeDecorator {
public Milk(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", 우유 추가";
}
@Override
public double cost() {
return coffee.cost() + 500;
}
}
// 5. ConcreteDecorator (구체적인 데코레이터: 시럽 추가)
class Syrup extends CoffeeDecorator {
public Syrup(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", 시럽 추가";
}
@Override
public double cost() {
return coffee.cost() + 300;
}
}
// 6. 사용 예시
public class DecoratorPatternExample {
public static void main(String[] args) {
Coffee basicCoffee = new BasicCoffee();
System.out.println(basicCoffee.getDescription() + " 가격: " + basicCoffee.cost() + "원");
Coffee milkCoffee = new Milk(basicCoffee);
System.out.println(milkCoffee.getDescription() + " 가격: " + milkCoffee.cost() + "원");
Coffee syrupMilkCoffee = new Syrup(milkCoffee);
System.out.println(syrupMilkCoffee.getDescription() + " 가격: " + syrupMilkCoffee.cost() + "원");
}
}
기본 커피 가격: 3000원
기본 커피, 우유 추가 가격: 3500원
기본 커피, 우유 추가, 시럽 추가 가격: 3800원