핵심 의도
데코레이터 패턴으로 객체에 추가 요소를 실행 중에 동적으로 더할 수 있다. 데코레이터를 사용하면 서브클래스를 만들 때보다 훨씬 유연하게 기능을 확장할 수 있다.
적용 상황
감싸고 있는 객체에 행동을 추가하거나 위임하는 용도로 만들어진다. 예를 들어 문자열을 다양한 방법으로 출력하고 싶을 때 사용할 수 있다. 문장 앞에 줄번호를 붙이거나, 소문자로 바꾸어 출력하거나, 박스로 감싸서 출력할 수 있다. 이때 문자열은 감싸지는 객체이고 추가하는 행동은 데코레이터의 책임이다.
솔루션의 구조와 각 요소의 역할
객체에게 책임을 분할하기
어떤 객체와 상호작용하는 다른 객체들은 그 객체의 장식의 유무와 상관없이 그 객체에게 메시지를 보낸다. 데코레이터에게도 원래 객체와 동일한 메시지 요청이 오므로, 이 메시지를 수신하려면 데코레이터와 감싸지는 객체는 같은 타입이어야 한다.
감싸지는 객체의 책임은 ConcreateComponent에, 장식의 책임은 Decorator에 할당한다. 이 둘은 같은 타입이어야 하므로 Component를 구현하거나 상속한다. 장식 기능의 구체적인 구현은 ConcreteDecorator에서 담당한다.
구현 포인트
데코레이터 패턴은 OCP 규칙을 효과적으로 지킬 수 있는 패턴이다. OCP는 기존 코드를 변경하지 않고 확장으로 새로운 행동을 추가하는 기법이다. 요구사항이 변경이 발생하는 상황에서 유연하게 코드를 관리할 수 있다.
적용 예시
요구사항
커피의 주문 시스템 구축하기. 현재 커피의 종류는 HouseBlend, DarkRoast, Decaf, Espresso가 있고 추가할 수 있는 메뉴는 Milk, Soy, Mocha, Whip가 있다.
설계
Beverage (감싸지는 객체와 데코레이터의 추상 클래스)
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
CondimentDecorator (데코레이터 추상 클래스)
public abstract class CondimentDecorator extends Beverage {
Beverage beverage;
public abstract String getDescription();
}
DarkRoast (감싸지는 객체)
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "Dark Roast Coffee";
}
public double cost() {
return .99;
}
}
Milk (데코레이터 객체)
public class Milk extends CondimentDecorator {
public Milk(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
public double cost() {
return .10 + beverage.cost();
}
}
Entry Point
public static void main(String args[]) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()
+ " $" + beverage.cost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()
+ " $" + beverage2.cost());
Beverage beverage3 = new HouseBlend();
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
System.out.println(beverage3.getDescription()
+ " $" + beverage3.cost());
}
데코레이터 패턴을 적용한 객체와 데코레이터들은 외부에서 받은 메시지 요청을 내부에서 연쇄적으로 처리한다.
'OOP > <헤드 퍼스트 디자인 패턴>, 에릭 프리먼 외' 카테고리의 다른 글
Singleton (0) | 2023.02.24 |
---|---|
Simple Factory, Factory Method, Abstract Factory (0) | 2023.02.24 |
Observer (0) | 2023.02.24 |
Strategy (0) | 2023.02.24 |
공부 방법 설정 (0) | 2023.02.24 |