학습 목표
- 객체의 기능 확장을 상속이 아닌 합성(Composition)으로 해결하는 방식을 이해한다.
- OCP(개방-폐쇄 원칙) — 기존 코드를 변경하지 않고 기능을 확장하는 원칙을 실전에서 적용한다.
- 런타임에 동적으로 기능 추가가 필요한 상황에서 데코레이터를 적용할 수 있게 한다.
- 프레임워크에서 **데코레이터 사용 사례(Spring 필터, InputStream, OutputStream)**를 이해한다.
활용 예제
- 커피 주문 시스템에서 고객이 샷 추가, 우유 추가, 시럽 추가 등을 선택할 수 있는 경우
- HTTP 요청 처리 필터 체인
- 로그 처리에 타임스탬프, 라벨, 파일 저장 기능을 겹겹이 추가하는 구조
예제
더보기
Coffee에서 에스프레소와 밀크를 추가하는 거에 따른 가격 변동을 확인
- 컴포넌트 기본 인터페이스
public interface Coffee {
String getDescription();
int getCost();
}
- 기본 구현 클래스
public class BasicCoffee implements Coffee {
@Override
public String getDescription() {
return "Basic Coffee";
}
@Override
public int getCost() {
return 3000;
}
}
- 데코레이터 추상 클래스
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public String getDescription() {
return coffee.getDescription();
}
@Override
public int getCost() {
return coffee.getCost();
}
}
- 구체적인 데코레이터
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", Milk";
}
@Override
public int getCost() {
return super.getCost() + 500;
}
}
public class ShotDecorator extends CoffeeDecorator {
public ShotDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", Extra Shot";
}
@Override
public int getCost() {
return super.getCost() + 700;
}
}
- 구현
public class Main {
public static void main(String[] args) {
Coffee coffee = new BasicCoffee();
coffee = new MilkDecorator(coffee);
coffee = new ShotDecorator(coffee);
System.out.println(coffee.getDescription()); // Basic Coffee, Milk, Extra Shot
System.out.println(coffee.getCost()); // 4200
}
}
- 기본 coffee를 생성해서 우유를 추가하고, 샷을 추가하는 과정을 나타내며 coffee를 체인으로 계속 가져가면서 가격이 상승하는 효과가 있다.
마무리
데코레이터 패턴은 기능 확장에 유리하다는 장점이 있는 것 같고, Lombok에 @Builder가 해당 패턴을 이용해서 만들어졌다고 합니다. 이렇든 확장설계가 필요할 때 고려해 주면 좋을 것 같습니다.
'Java > 패턴' 카테고리의 다른 글
| 책임사슬 패턴 ( Chain of Resposibility Pattern) (0) | 2025.12.01 |
|---|---|
| 방문자 패턴 ( Visitor Pattern ) (0) | 2025.11.27 |
| 컴포지트 패턴 ( Composite Pattern ) (0) | 2025.11.25 |
| 브릿지 패턴 ( Bridge Pattern ) (0) | 2025.11.24 |
| 추상 팩토리 패턴 ( Abstract Factory Pattern ) (0) | 2025.11.23 |