객체에 추가적인 요건을 동적으로 첨가한다. 데코레이터는 서브클래스로 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다.
데코레이터 패턴을 사용하면 확장에 대한 내용을 캡슐화해 실행 중에 확장을 가능하게 해준다.
데코레이터 패턴 특징
- 데코레이터의 슈퍼클래스는 자신이 장식하는 객체의 슈퍼클래스와 같다.
-따라서 장식할 객체가 들어가던 자리에 데코레이터로 꾸민 객체가 들어갈 수 있다.- 한 객체를 여러 개의 데코레이터 객체로 감쌀 수 있다.
- 데코레이터는 자신이 장식하고 있는 객체에게 어떠 행동을 위임하는 것 외에 원하는 추가적인 작업을 수행 할 수 있다.
실제 데코레이터 활용
class Program
{
static void Main()
{
Component instance = new ConcreteComponent1();
instance = new ConcreteDecorator1(instance);
instance = new ConcreteDecorator2(instance);
instance.methodA();
}
}
여기서 methodA() 가 호출되는 경로를 확인해보면
Decorator의 methodA들이 추가적인 행동을 실행하고 이전 Decorator 아니면 Component의 methodA를 호출하면서 기존 내용외 추가적인 작업처리를 할 수 있게 된다.
데코레이터 사용시 주의점
- lapper 클래스가 너무 많아져 관리하기 어려워 질 수 있다.
- 초기화 작업시 lapping 과정이 추가되 복잡해진다.
- 구상 구성요소를 바탕으로 코드를 작성할 수 없다. 추상구성요소를 바탕으로만 접근가능
특히 구상 구성요소를 바탕으로 코드를 작성할 수 없다는 것은 특정 형식에 의존하는 코드작성 시 원하는데로 작동하지 않는다는 것이다.
예를 들어
class Program
{
static void Main()
{
//instance의 형식을 구상 class로 바꿈
ConcreteComponent1 instance = new ConcreteComponent1();
//error : ConcreteDecorator1은 ConcreteComponent1을 구현하지 않으므로
instance = new ConcreteDecorator1(instance);
instance = new ConcreteDecorator2(instance);
instance.methodA();
}
}
따라서 데코레이터 패턴은 추상 구성요소를 바탕으로 코드를 작성해야한다.