상위문서: GoF 디자인 패턴
객체에 동적으로 새로운 책임(responsibility)을 추가할 수 있게 하는 패턴
서브클래스를 생성하는 것보다 융통성 있는 방법을 제공한다.
예를 들어, GUI 툴킷에 모든 사용자 인터페이스 요소에는 필요 없지만, 특정 인터페이스 요소에만 스크롤링과 같은 행동이나 또는 테두리 속성을 추가할 수 있도록 해줄 필요가 있을 때.
이 예제는 음료(component)와 첨가물(decorator) 조합의 구현을 데코레이터 패턴으로 해결하고 있다.
// 음료
abstract class Beverage {
String description = "제목 없음";
public String getDescription() { return description; }
public abstract double cost();
@Override
public String toString() {
return getDescription() + ": $" + cost();
}
}
// 첨가물
abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
다음은 베이스가 되는 두 가지 음료이다.
class Espresso extends Beverage {
public Espresso() { description = "에스프레소"; }
@Override
public double cost() { return 1.99; }
}
class HouseBlend extends Beverage {
public HouseBlend() { description = "하우스 블렌드 커피"; }
@Override
public double cost() { return 0.89; }
}
다음은 모카 첨가물. 이 외에도 두유, 휘핑 크림 등 다양한 첨가물을 만들 수 있다.
class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
description = "모카";
this.beverage = beverage;
}
@Override
public double cost() {
// 중요한 부분
return 0.20 + beverage.cost();
}
@Override
public String getDescription() {
// 중요한 부분
return beverage.getDescription() + ", " + description;
}
}
사용 시에
Beverage beverage = new Espresso();
System.out.println(beverage);
beverage = new Mocha(beverage);
System.out.println(beverage);
Beverage beverage2 = new HouseBlend();
System.out.println(beverage2);
beverage2 = new Mocha(beverage2);
System.out.println(beverage2);
결과
에스프레소: $1.99
에스프레소, 모카: $2.19
하우스 블렌드 커피: $0.89
하우스 블렌드 커피, 모카: $1.09
java.io 패키지에서 데코레이터 패턴을 사용한다.