데코레이터 패턴(Decorator pattern)
데코레이터 패턴이란?
객체에 추가적인 책임을 동적으로 덧붙이는 패턴이다.
상속을 사용하지 않아 유연하다고 많이 표현한다.
조금씩 기능을 추가하여 새로운 클래스를 생성한다고 생각해보자
상속을 하여 클래스를 조금씩 만들면 너무 많은 상속관계가 형성된다.
이렇게 되면 관리가 너무 어려워진다.
변경 사항이 하나라도 생기면 많은 수정사항이 발생하게 된다.
추가 기능을 Decorator 클래스로 만들어 런타임에서 다양한 조합을 클라이언트가 원하는 데로 생성합니다.
예시를 보자

- Component
추상 클래스 혹은 인터페이스로 구현합니다.
객체의 다형성을 활용해 Component클래스로 객체를 정의하고 사용한다.
- ConcreteComponent
기본적인 기능을 가지는 객체이다.
이 객체를 Decorate 합니다.
- Decorator
여러 가지의 Decorator의 공통적인 기능을 제공하며 인터페이스나 추상 클래스 역할을 합니다.
- ConcreteDecorator
Decorator를 상속받아 구체적인 추가 기능을 만듭니다.
Decorator 패턴을 사용해보자
커피숍에서 여러 가지 커피를 만들어보자
DarkRost를 베이스로
Mocha와 Whip을 추가하여 커피를 만들어보자
abstract class Beverage {
String description = "제목없음";
public String getDescription() {
return description;
}
public abstract double cost();
}
Component역할을 하는 Beverage클래스이다.
class DarkRoast extends Beverage {
public DarkRoast() {
description = "Dark roast";
}
public double cost() {
return 1.99;
}
}
ConcreateComponent역할을 하는 DarkRoast이다.
이 객체를 Decorate 하게 된다.
abstract class Decorator extends Beverage {
public abstract String getDescription();
}
Decorator 클래스이다.
구체적인 Decorator가 상속을 받는다.
class Mocha extends Decorator{
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage= beverage;
}
public String getDescription() {
return beverage.getDescription() + ", 모카";
}
public double cost() {
return beverage.cost() + .20;
}
}
class Whip extends Decorator{
Beverage beverage;
public Whip(Beverage beverage) {
this.beverage= beverage;
}
public String getDescription() {
return beverage.getDescription() + ", 휘핑";
}
public double cost() {
return beverage.cost() + .20;
}
}
ConcreateDecorator인 Whip과 Mocha이다.
public class Main{
public static void main(String args[]) {
Beverage b = new DarkRoast();
b = new Mocha(b);
b = new Whip(b);
System.out.println(b.getDescription()
+ " $" + b.cost());
}
}
클라이언트는 DarkRoast를 객체를 만들어 Mocha와 Whip으로 Decorate를 하여 원하는 객체를 만든다.