Ch3. 데코레이터 패턴 : 객체 꾸미기
OCP(Open-Closed Principle)
클래스는 확장에는 열려 있어야 하지만 변경에는 닫혀 있어야 한다.
데코레이터 패턴
데코레이터의 슈퍼클래스는 자신이 장식하고 있는 객체의 슈퍼클래스와 같다.
한 객체를 여러 개의 데코레이터로 감쌀 수 있다.
데코레이터는 자신이 감싸고 있는 객체와 같은 슈퍼클래스를 가지고 있기에 원래 객체(싸여 있는 객체)가 들어갈 자리에 데코레이터 객체를 넣어도 상관없다.
데코레이터는 자신이 장식하고 있는 객체에게 어떤 행동을 위임하는 일 말고도 추가 작업을 수행할 수 있다.
객체는 언제든지 감쌀 수 있으므로 실행 중에 필요한 데코레이터를 마음대로 적용할 수 있다.
💡 데코레이터 패턴으로 객체에 추가 요소를 동적으로 더할 수 있다. 데코레이터를 사용하면 서브클래스를 만들 때보다 훨씬 유연하게 기능을 확장할 수 있다.

행동을 상속받으려고 Beverage의 서브클래스를 만든 게 아니라 형식으로 맞추려고 한 것
만약 상속만 서야 했다면 행동이 컴파일 시에 정적으로 결정됨. 하지만 구성을 활용하면 실행 중에 데코레이터를 마음대로 조합해서 사용할 수 있다는 장점이 있다.
→ 데코레이터를 언제든지 구현해서 새로운 행동을 추가할 수 있음.
커피 주문 시스템 코드 예제
public abstract class Beverage {
String description = "제목 없음";
public String getDescription() {
return description;
}
public abstract double cost();
}
첨가물(condiment)를 나타내는 추상클래스(데코레이터 클래스)
public abstract class CondimentDecorator extends Beverage {
Beverage beverage; // 각 데코레이터가 감쌀 음료를 나타내는 Beverage 객체 지정
public abstract String getDescription();
}
음료 코드 구현
public class Espresso extends Beverage {
public Espresso() {
description = "에스프레소";
}
public double cost() {
return 1.99.
}
}
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "하우스 블렌드 커피";
}
public double cost() {
return .89;
}
}
첨가물 코드 구현
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;
}
}
Mocha 인스턴스에는 Beverage의 레퍼런스가 들어있다.
두가지가 필요하다
감싸고자 하는 음료를 저장하는 인스턴스 변수
인스턴스 변수를 감싸고자하는 객체로 설정하는 생성자(데코레이터의 생성자에 감싸고자 하는 음료 객체를 전달하는 방식을 사용)
데코레이터 적용 예시 : 자바 I/O
java.io 패키지
Last updated