데코레이터 패턴
개요
데코레이터 패턴은 객체 지향 디자인 패턴 중 하나로, 기존 객체의 기능을 동적으로 확장할 수 있는 패턴이다. 이 패턴은 객체에 추가적인 책임을 동적으로 더할 수 있으며, 상속보다 유연한 확장이 가능하다.
구성요소
데코레이터 패턴은 다음과 같은 구성요소로 이루어져 있다.
Component
Component는 데코레이터 패턴에서 기능을 확장할 대상이 되는 객체의 공통 인터페이스를 정의한다.
ConcreteComponent
ConcreteComponent는 Component의 구현 클래스이다.
Decorator
Decorator는 Component의 구현체와 동일한 인터페이스를 가지며, Component의 기능을 동적으로 확장하기 위한 추상 클래스이다.
ConcreteDecorator
ConcreteDecorator는 Decorator의 구현 클래스이며, 기존 Component에 추가적인 기능을 더해준다.
활용 예시
데코레이터 패턴은 다음과 같은 상황에서 유용하게 사용될 수 있다.
•
기존 객체의 기능을 유지하면서 추가적인 기능을 더해야 할 때
•
상속으로 인한 클래스의 갯수 증가를 막기 위해
•
객체의 구성요소 중 일부에만 기능을 추가해야 할 때
예시 코드
아래는 데코레이터 패턴의 예시 코드이다.
public interface Pizza {
String getDescription();
double getCost();
}
public class PlainPizza implements Pizza {
@Override
public String getDescription() {
return "Plain Pizza";
}
@Override
public double getCost() {
return 4.00;
}
}
public abstract class ToppingDecorator implements Pizza {
private Pizza tempPizza;
public ToppingDecorator(Pizza newPizza){
tempPizza = newPizza;
}
@Override
public String getDescription() {
return tempPizza.getDescription();
}
@Override
public double getCost() {
return tempPizza.getCost();
}
}
public class Mozzarella extends ToppingDecorator {
public Mozzarella(Pizza newPizza) {
super(newPizza);
System.out.println("Adding Mozzarella");
}
@Override
public String getDescription() {
return super.getDescription() + ", Mozzarella";
}
@Override
public double getCost() {
return super.getCost() + 0.50;
}
}
public class TomatoSauce extends ToppingDecorator {
public TomatoSauce(Pizza newPizza) {
super(newPizza);
System.out.println("Adding Tomato Sauce");
}
@Override
public String getDescription() {
return super.getDescription() + ", Tomato Sauce";
}
@Override
public double getCost() {
return super.getCost() + 0.35;
}
}
Plain Text
복사
위 코드는 Pizza 인터페이스를 구현하는 ConcreteComponent 클래스인 PlainPizza와, Decorator 추상 클래스인 ToppingDecorator, ConcreteDecorator 클래스인 Mozzarella와 TomatoSauce를 구현한 코드이다. PlainPizza 객체에 Mozzarella와 TomatoSauce를 추가하기 위해 다음과 같은 코드를 작성할 수 있다.
Pizza basicPizza = new TomatoSauce(new Mozzarella(new PlainPizza()));
Plain Text
복사
이를 실행한 결과는 다음과 같다.
Adding Mozzarella
Adding Tomato Sauce
Plain Text
복사
또한, basicPizza 객체의 getDescription()과 getCost() 메소드를 호출하면 각각 "Plain Pizza, Mozzarella, Tomato Sauce"와 4.85가 반환된다.
결론
데코레이터 패턴은 객체에 기능을 동적으로 추가하거나 제거할 수 있는 유연한 방법이다. 이 패턴은 객체 지향 디자인에서 꼭 알아둬야 하는 중요한 패턴 중 하나이다.