-
구조 패턴(Structural Pattern) - 데코레이터(Decorator) 패턴Java/디자인패턴 2024. 11. 20. 09:25반응형
1. 소속 카테고리
데코레이터 패턴은 **구조 패턴(Structural Pattern)**에 속합니다. 구조 패턴은 클래스나 객체를 조합하여 더 큰 구조를 형성하거나, 객체 간의 관계를 효율적으로 구성하는 데 초점을 맞춥니다.
2. 특징
- 객체에 동적으로 새로운 기능을 추가할 수 있습니다.
- 기존 객체를 수정하지 않고도 기능 확장이 가능하여 **개방-폐쇄 원칙(OCP)**을 준수합니다.
- 상속을 사용하지 않고도 유연하게 기능을 확장할 수 있습니다.
3. 주요 구성 요소
- Component (기본 인터페이스/추상 클래스): 기본 객체의 공통된 인터페이스를 정의합니다.
- ConcreteComponent: 기본 객체로, 기본 동작을 구현합니다.
- Decorator: Component를 구현하거나 상속받아 동적으로 기능을 추가할 수 있는 클래스입니다.
- ConcreteDecorator: Decorator의 구체적인 구현체로, 추가된 동작을 정의합니다.
4. Java 예제
요구 사항:
커피(Coffee) 주문 시스템을 구현해야 합니다.
- 기본 커피에 우유, 설탕 등 추가 옵션을 동적으로 선택할 수 있어야 합니다.
- 각 옵션은 가격을 추가하며, 조합에 따라 가격이 계산됩니다.
// Component 인터페이스 public interface Coffee { String getDescription(); double getCost(); } // ConcreteComponent public class BasicCoffee implements Coffee { @Override public String getDescription() { return "Basic Coffee"; } @Override public double getCost() { return 2.0; // 기본 커피 가격 } } // Decorator 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 double getCost() { return coffee.getCost(); } } // ConcreteDecorator 1 public class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); } @Override public String getDescription() { return coffee.getDescription() + ", Milk"; } @Override public double getCost() { return coffee.getCost() + 0.5; // 우유 추가 비용 } } // ConcreteDecorator 2 public class SugarDecorator extends CoffeeDecorator { public SugarDecorator(Coffee coffee) { super(coffee); } @Override public String getDescription() { return coffee.getDescription() + ", Sugar"; } @Override public double getCost() { return coffee.getCost() + 0.2; // 설탕 추가 비용 } } // Client 코드 public class DecoratorPatternExample { public static void main(String[] args) { Coffee basicCoffee = new BasicCoffee(); System.out.println(basicCoffee.getDescription() + " -> $" + basicCoffee.getCost()); Coffee milkCoffee = new MilkDecorator(basicCoffee); System.out.println(milkCoffee.getDescription() + " -> $" + milkCoffee.getCost()); Coffee milkSugarCoffee = new SugarDecorator(milkCoffee); System.out.println(milkSugarCoffee.getDescription() + " -> $" + milkSugarCoffee.getCost()); } }
5. 코드 실행 결과
Basic Coffee -> $2.0 Basic Coffee, Milk -> $2.5 Basic Coffee, Milk, Sugar -> $2.7
6. 장점
- 유연성: 기존 객체를 수정하지 않고도 기능 확장 가능.
- 재사용성: 다양한 데코레이터를 조합하여 새로운 동작을 쉽게 생성.
- 개방-폐쇄 원칙 준수: 새로운 데코레이터를 추가해도 기존 코드에 영향을 주지 않음.
7. 단점
- 데코레이터를 많이 중첩하면 Java 코드가 복잡해질 수 있음.
- 디버깅이 어렵고, 객체 식별이 복잡해질 수 있음.
반응형'Java > 디자인패턴' 카테고리의 다른 글
행동(Behavioral) - 메멘토(Memento) 패턴 (0) 2024.11.22 행동(Behavioral) - 커맨드(Command) 패턴 (0) 2024.11.21 생성 패턴(Creational Pattern) - 빌더(Builder) 패턴 (0) 2024.11.19 행동(Behavioral) - 방문자(Visitor) 패턴 (0) 2024.11.18 행동(Behavioral) - 중재자(Mediator) 패턴 (0) 2024.11.17