inblog logo
|
stupefyee
    디자인패턴

    [디자인 패턴] 데코레이터 패턴

    Stupefyee's avatar
    Stupefyee
    Nov 13, 2024
    [디자인 패턴] 데코레이터 패턴
    Contents
    1. 개요2. 구성 요소3. 장점4. 단점5. Java 코드 예시6. 비교: 데코레이터 vs 상속7. 결론
    💡
    객체들을 새로운 행동들을 포함한 특수 래퍼 객체들 내에 넣어서 위 행동들을 해당 객체들에 연결시키는 구조적 디자인 패턴

    1. 개요

    • 객체의 기능을 동적으로 추가하는 구조적 패턴.
    • 상속 대신 객체를 감싸서 기능을 확장.
    • 기존 객체를 변경하지 않고 기능을 추가할 수 있음.

    2. 구성 요소

    • Component: 기능을 추가할 기본 인터페이스.
    • ConcreteComponent: 기본 객체로, 실제 기능을 구현.
    • Decorator: 기본 객체를 감싸는 추상 클래스.
    • ConcreteDecorator: 기능 추가를 위한 구체적 클래스.

    3. 장점

    • 유연성: 런타임 중에 기능을 동적으로 추가.
    • 재사용성: 다양한 객체에서 기능을 재사용 가능.
    • 응집성: 기능별로 독립적인 클래스로 관리.

    4. 단점

    • 객체 수 증가: 데코레이터가 많으면 객체 수가 증가.
    • 복잡성 증가: 데코레이터가 많을수록 조합을 관리하기 어려움.

    5. Java 코드 예시

    5.1. Coffee 인터페이스 (Component)

    java 코드 복사 // Component: 기본 인터페이스 public interface Coffee { double cost(); // 가격을 반환하는 메서드 }

    5.2. SimpleCoffee 클래스 (ConcreteComponent)

    java 코드 복사 // ConcreteComponent: 기본 커피 객체 public class SimpleCoffee implements Coffee { @Override public double cost() { return 5.0; // 기본 커피 가격 } }

    5.3. CoffeeDecorator 클래스 (Decorator)

    java 코드 복사 // Decorator: 기본 객체를 감싸는 추상 클래스 public abstract class CoffeeDecorator implements Coffee { protected Coffee coffee; // 기본 커피 객체 // 생성자를 통해 기본 커피 객체를 설정 public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; } @Override public double cost() { return coffee.cost(); // 기본 커피 가격 반환 } }

    5.4. MilkDecorator 클래스 (ConcreteDecorator)

    java 코드 복사 // ConcreteDecorator: 우유 추가 public class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); // 기본 커피 객체 설정 } @Override public double cost() { return super.cost() + 2.0; // 우유 추가 비용 2.0 더하기 } }

    5.5. SugarDecorator 클래스 (ConcreteDecorator)

    java 코드 복사 // ConcreteDecorator: 설탕 추가 public class SugarDecorator extends CoffeeDecorator { public SugarDecorator(Coffee coffee) { super(coffee); // 기본 커피 객체 설정 } @Override public double cost() { return super.cost() + 1.0; // 설탕 추가 비용 1.0 더하기 } }

    5.6. 테스트 클래스 (클라이언트 코드)

    java 코드 복사 // 테스트 클래스: 데코레이터 패턴 사용 예시 public class DecoratorPatternTest { public static void main(String[] args) { Coffee simpleCoffee = new SimpleCoffee(); System.out.println("Simple Coffee cost: " + simpleCoffee.cost()); // 우유 추가된 커피 Coffee milkCoffee = new MilkDecorator(simpleCoffee); System.out.println("Milk Coffee cost: " + milkCoffee.cost()); // 설탕과 우유가 추가된 커피 Coffee milkSugarCoffee = new SugarDecorator(milkCoffee); System.out.println("Milk and Sugar Coffee cost: " + milkSugarCoffee.cost()); // 설탕, 우유, 기본 커피가 추가된 커피 Coffee fullyDecoratedCoffee = new SugarDecorator(new MilkDecorator(new SimpleCoffee())); System.out.println("Fully decorated Coffee cost: " + fullyDecoratedCoffee.cost()); } }

    5.6. 동작 예시

    💡
    Simple Coffee cost: 5.0 Milk Coffee cost: 7.0 Milk and Sugar Coffee cost: 8.0 Fully decorated Coffee cost: 8.0

    6. 비교: 데코레이터 vs 상속

    ㅤ
    데코레이터
    상속
    기능 추가
    동적으로 기능 추가
    서브클래스를 통해 기능 추가
    유연성
    기능을 런타임에 조합 가능
    컴파일 타임에 고정된 기능
    객체 수
    객체 수 증가
    클래스 수 증가

    7. 결론

    • 상속 대신 객체를 감싸서 기능을 동적으로 확장.
    • 다양한 기능을 독립적으로 관리할 수 있어, 유연하고 확장성 있는 코드 작성 가능.
    • 기존 객체를 수정하지 않고 기능을 추가하는 방식으로 응집력을 높이고, 변경에 강한 구조를 제공.
    Share article
    Contents
    1. 개요2. 구성 요소3. 장점4. 단점5. Java 코드 예시6. 비교: 데코레이터 vs 상속7. 결론

    stupefyee

    RSS·Powered by Inblog