데코레이터 패턴이란?
디자인 패턴 중 하나로 객체의 덧붙임을 통해 기능 등을 동적으로 유연하게 확장할 수 있는 패턴이다.
예시
GUI에서 윈도우 창 하나를 나타내는 Window 라는 타입에 가로 스크롤, 새로 스크롤, 전체 화면 기능을 추가한다고 해보자.
데코레이터 패턴을 사용하지 않은 경우
public class Window {
public void draw() {
// draw window
}
public String getDescription() {
return "simple window";
}
}
public class WindowWithVerticalScrollBar extends Window {
public WindowWithVerticalScrollBar () {
super();
}
@Override
public void draw() {
super.draw();
// draw window
}
@Override
public String getDescription() {
return super.getDescription() + ", including vertical scrollbars";
}
}
public class WindowWithHorizonScrollBar extends Window {
public WindowWithHorizonScrollBar () {
super();
}
@Override
public void draw() {
super.draw();
// draw window
}
@Override
public String getDescription() {
return super.getDescription() + ", including horizon scrollbars";
}
}
위와 같이 새로운 기능을 구현하게 된다면 새로운 기능이 추가될 때마다 클래스의 종류가 기하급수적으로 늘어난다 지금 위의 3가지 기능을 추가한다면 가능한 모든 클래스를 다만드려면 $2^n$개의 클래스를 만들어야된다.
데코레이터 패턴을 사용한 경우
데코레이터 패턴의 기본적이 구조는 아래와 같다.
Component
: 기본 기능과 추가 기능의 공통적인 책임을 명세하는 인터페이스ConcreteComponent
: 기본 기능을 구현한 클래스Decorator
: 추가 기능으로 가질 책임들의 추상 클래스ConcreteDecorator
:Decorator
를 상속받아 추가 기능을 구현한 클래스
interface Window {
void draw();
String getDescription();
}
class SimpleWindow implements Window {
@Override
public void draw() {
// draw window
}
@Override
public String getDescription() {
return "simple window";
}
}
abstract class WindowDecorator implements Window {
private Window decoratedWindow;
public WindowDecorator (Window decoratedWindow) {
this.decoratedWindow = decoratedWindow;
}
@Override
public void draw() {
decoratedWindow.draw();
}
@Override
public String getDescription() {
return decoratedWindow.getDescription();
}
}
class VerticalScrollBarDecorator extends WindowDecorator {
public VerticalScrollBarDecorator(Window decoratedWindow) {
super(decoratedWindow);
}
@Override
public void draw() {
super.draw();
// draw vertical scrolls
}
@Override
public String getDescription() {
return super.getDescription() + ", including vertical scrollbars";
}
}
class HorizontalScrollBarDecorator extends WindowDecorator {
public HorizontalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}
public void draw() {
drawHorizontalScrollBar();
super.draw();
}
private void drawHorizontalScrollBar() {
// draw the horizontal scrollbar
}
public String getDescription() {
return super.getDescription() + ", including horizontal scrollbars";
}
}
Window
가 Component
, SimpleWindow
가 ConcreteComponent
, WindowDecorator
가 Decorator
에 해당한다. 아래와 같은 방법으로 여러 기능을 추가하여 사용할 수 있다.
Window windowWithVerticalAndHorizontalScroll
= new HorizontalScrollBarDecorator(
new VerticalScrollBarDecorator(
new SimpleWindow()));
System.out.println(windowWithVerticalAndHorizontalScroll.getDescription());
결과는 가장 먼저 생성된 SimpleWindow부터 시작하여 simple window, including vertical scrollbars, including horizontal scrollbars
가 출력된다. 이런 식으로 생성자에 추가할 기능을 이어 붙여서 원하는 기능들만 조합한 객체를 생성할 수 있다.
참고 자료
https://gmlwjd9405.github.io/2018/07/09/decorator-pattern.html
댓글남기기