디자인패턴 Decorator Pattern

황제낙엽 2007.04.21 15:17 조회 수 : 15

sitelink1  
sitelink2  
sitelink3  
extra_vars4  
extra_vars5  
extra_vars6  

1. 개요
자바 I/O패키지에 적용된 패턴이다.
개념적으로는 모든 클래스는 하나의 super클래스를 상속받아 생성자의 파라미터로써 부모 객체를 물려받아 내장된 인스턴스 변수의 값을 변형하는 작업을 하도록 한다.
이는 각 클래스를 거쳐가면서 남겨지는 히스토리의 의미와는 전혀 다르고 단지 클래스를 이동하면서 값이 변화하고 있다는 것에 초점을 맞추고 있다.
이러한 개념은 오히려 자바 I/O보다는 네트웍의 ip 로그를 남기는 행위와 비슷하지 않을까 라고 생각한다.
추상적인 개념은 기존의 클래스를 랩핑하여 새로운 기능을 덧씌운다는 것으로써 코드로써 구현한다면 새로운 클래스의 생성자에 기존 객체를 넘겨줘서 전역변수로 셋팅해주고
새로운 클래스의 메소드에서 기존 클래스의 객체에 접근하여 메소드를 수행하면서 결과물에 대해 추가적인 작업을 덧붙이도록 할 수 있다.


2. 컨텍스트
어떤 객체에 대해 동적으로 부가적인 책임(responsibilities)을 부여하고자 할 때 사용된다.
Decorator 패턴은 기능을 확장하거나, 서브 클래스를 생성하는 것에 대해 유연한 대안을 제공한다.
어떤 클래스에 대해서 테두리(border)를 부여하고자 하는 경우, 상속을 통해 테두리를 갖는 하위 클래스를 만들 수 있다.
그러나, 이는 정적인 방법으로 테두리가 생성되어, 테두리가 생기는 시점이나 방법을 통제할 수가 없다.
이보다 유연한 방법은 테두리를 갖는 객체가 테두리를 갖고자 하는 객체를 포함하는 것이다.
이렇게 부가적인 기능을 원하는 객체를 포함하는 객체를 Decorator라고 부른다.



위 그림은 aTextView라고 하는 객체에 스크롤(scroll)과 테두리를 추가하고자 하는 경우, 상속을 통해 클래스를 확장하지 않고, 이를 위한 Decorator를 생성하여 해결하는 모습을 나타낸다.

3. 적용 영역
다른 객체에 영향을 미치지 않으면서, 특정 객체에 동적으로 책임(responsibilities)을 추가하려는 경우 사용한다.
클래스 정의를 알 수 없는 경우와 같이 상속을 통한 클래스의 확장을 할 수 없는 경우


4. 구조



5. 적용 결과
정적인 상속을 이용하는 것보다 유연하다.
계층구조를 따라 기능이 누적되는 현상을 막을 수 있다. 
Decorator 패턴을 이용하면 필요한 만큼만 기능을 구현할 수 있다. 
따라서, 시스템이 작은 객체들의 상호 연결된 구조를 이루게 하여, 적절하게 수정(customize)하기는 수월하지만, 디버깅이 어려울 수 있다.

6. 관련 패턴
Decorator 패턴은 인터페이스 변환 없이 다른 객체의 개선이 가능하다. 순수하게 Adapter 패턴만 적용해서는 순환 구성(recursive composition)이 불가능하고, Decorator를 이용하면 가능하다.
Decorator 패턴은 종종 Composite 패턴과 함께 사용되어, 공통의 부모 클래스를 갖는다. 이때, Decorator가 add, remove 및 getChild와 같은 Component 인터페이스를 지원해야 한다.
Decorator 패턴이 객체의 피부를 바꿀 수 있게 해준다면, Strategy 패턴은 객체의 내장을 바꿀 수 있게 해준다. 이들은 객체 변경을 위한 두 가지 선택사항이 된다.