디코레이터 패턴: 동적 기능 확장 방법

디코레이터 패턴 개요 디코레이터 패턴은 객체의 기능을 동적으로 확장할 수 있도록 하는 구조적 디자인 패턴입니다. 이 패턴은 기존 클래스를 수정하지 않고 추가적인 책임을 부여할 수 있는 메커니즘을 제공하며, 특히 단일 책임 원칙을 준수하는 시스템에서 유용하게 활용됩니다.

구성 요소

  • 인터페이스: 기능 확장이 가능한 기본 객체 타입 정의
  • 기본 클래스: 인터페이스를 구현한 기본 구현체
  • 디코레이터 추상 클래스: 기본 객체를 감싸는 래퍼 클래스로, 동적 확장 기능 제공
  • 구체적 디코레이터: 추가 기능을 구현한 실제 확장 클래스

실무 예시 다음은 음료 제작 시스템을 대상으로 한 예제입니다:

// 기본 인터페이스
public interface Drink {
    double getPrice();
}

// 기본 구현체
public class BasicDrink implements Drink {
    @Override
    public double getPrice() {
        return 8000; // 기본 가격 8,000원
    }
}
// 디코레이터 추상 클래스
public abstract class DrinkDecorator implements Drink {
    protected Drink wrappedDrink;

    public DrinkDecorator(Drink drink) {
        this.wrappedDrink = drink;
    }

    @Override
    public double getPrice() {
        return wrappedDrink.getPrice();
    }
}
// 추가 기능 구현 클래스
public class MilkDecorator extends DrinkDecorator {
    public MilkDecorator(Drink drink) {
        super(drink);
    }

    @Override
    public double getPrice() {
        return super.getPrice() + 1500; // 우유 추가 1,500원
    }
}
public class WhipDecorator extends DrinkDecorator {
    public WhipDecorator(Drink drink) {
        super(drink);
    }

    @Override
    public double getPrice() {
        return super.getPrice() + 1000; // 육류 추가 1,000원
    }
}

사용 예제

public class DecoratorDemo {
    public static void main(String[] args) {
        Drink basic = new BasicDrink();
        System.out.println("기본 음료 가격: " + basic.getPrice());

        Drink milk = new MilkDecorator(basic);
        System.out.println("우유 추가 음료 가격: " + milk.getPrice());

        Drink whip = new WhipDecorator(milk);
        System.out.println("육류 추가 음료 가격: " + whip.getPrice());
    }
}

이 패턴은 여러 레イヤ를 중첩하여 기능을 조합할 수 있는 유연성을 제공합니다. 각 디코레이터는 자신만의 책임을 명확히 하며, 클라이언트는 필요한 기능만 순차적으로 적용할 수 있습니다. 이 방식은 코드 재사용성 향상과 열린/폐쇄 원칙을 준수하는 설계에 효과적입니다.

태그: java DesignPattern DecoratorPattern OOP

7월 15일 03:21에 게시됨