본문 바로가기

카테고리 없음

GOF 데코레이터 패턴

SMALL

자바 데코레이터 패턴은 구조(Structural) 디자인 패턴 중 하나로, 객체에 동적으로 새로운 기능을 추가할 수 있는 패턴입니다. 이 패턴은 기존의 객체를 수정하지 않고 기능을 확장하고자 할 때 유용합니다.

주요 구성 요소:
- Component: 데코레이터 패턴에서 기능을 추가하고자 하는 객체가 구현하는 인터페이스 또는 추상 클래스입니다. 기본 기능을 정의하고, 데코레이터 객체들이 추가 기능을 구현할 때 이를 참조합니다.
- ConcreteComponent: 기본 기능을 구현하는 클래스입니다. Component 인터페이스를 구체적으로 구현합니다.
- Decorator: 기능을 추가하는 데코레이터 객체의 추상 클래스입니다. Component를 상속하고, 내부에 Component 객체를 유지합니다.
- ConcreteDecorator: 실제로 기능을 추가하는 구체적인 데코레이터 클래스입니다. Decorator 클래스를 상속하고, 추가적인 기능을 구현하며 Component 객체를 호출합니다.

데코레이터 패턴의 동작 방식은 다음과 같습니다:
- 기본 기능을 제공하는 ConcreteComponent 객체가 있습니다.
- Decorator 클래스는 Component 인터페이스를 상속받고, 내부에 Component 객체를 유지합니다.
- ConcreteDecorator 클래스는 Decorator 클래스를 상속받고, 추가적인 기능을 구현합니다. 이때, 내부에 유지하는 Component 객체의 메서드를 호출하여 기본 기능을 실행한 뒤, 추가 기능을 수행합니다.

데코레이터 패턴은 객체를 계층적으로 감싸고, 각 데코레이터 객체가 원하는 기능을 추가할 수 있도록 합니다. 이를 통해 기능의 조합을 유연하게 구성할 수 있습니다.

데코레이터 패턴은 자바의 I/O 라이브러리에서 많이 활용되며, GUI 컴포넌트에서도 일반적으로 사용됩니다. 추가적인 예시와 코드를 통해 더 자세히 이해할 수 있습니다.



// Component
interface Coffee {
    String getDescription();
    double getCost();
}

// ConcreteComponent
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double getCost() {
        return 1.0;
    }
}

// Decorator
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription();
    }

    @Override
    public double getCost() {
        return decoratedCoffee.getCost();
    }
}

// ConcreteDecorator
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", Milk";
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.5;
    }
}

// ConcreteDecorator
class WhipDecorator extends CoffeeDecorator {
    public WhipDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", Whip";
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.7;
    }
}

// 예시 사용
public class DecoratorPatternExample {
    public static void main(String[] args) {
        // 기본 커피 생성
        Coffee coffee = new SimpleCoffee();

        // 데코레이터를 이용해 추가 기능을 덧붙임
        coffee = new MilkDecorator(coffee);
        coffee = new WhipDecorator(coffee);

        // 최종 커피 정보 출력
        System.out.println("Description: " + coffee.getDescription());
        System.out.println("Cost: $" + coffee.getCost());
    }
}

위의 예시 코드에서는 데코레이터 패턴을 구현하기 위해 Coffee 인터페이스를 정의하고, SimpleCoffee 클래스에서 이를 구현합니다. CoffeeDecorator 추상 클래스는 Coffee 인터페이스를 상속받으며, 내부에 Coffee 객체를 유지합니다. MilkDecorator와 WhipDecorator 클래스는 CoffeeDecorator 클래스를 상속받고, 추가적인 기능을 구현합니다.

DecoratorPatternExample 클래스에서는 예시로 기본 커피를 생성한 후, MilkDecorator와 WhipDecorator를 이용해 추가 기능을 덧붙입니다. 마지막으로 최종 커피의 설명과 가격을 출력합니다.

LIST