장식자 패턴을 쓰면서 얻는 이익과 부담은 각각 두가지 입니다.
(만약 상속으로 구현을 해야합니다. ScrollableTextView, BorderedTextView 의 인터페이스 를 만들어야 하고 스크롤과 Border기능이 같이 있는 TextView 를 만들려면 BorderedScrollableTextView 클래스를 생성해야합니다. 이는 새로운 기능이 추가될때 마다 클래스가 추가되게 된다.)
( 필요한 비용만 그때 지불하는 방법)
package study.designpattern;
class VisualComponent {
public VisualComponent() {}
public void draw() {
System.out.println("VisualComponent.draw");
}
public void resize() {}
// ...
}
class Decorator extends VisualComponent {
public Decorator(VisualComponent visualComponent) {
this.visualComponent = visualComponent;
}
@Override
public void draw() {
visualComponent.draw();
}
@Override
public void resize() {
visualComponent.resize();
}
private VisualComponent visualComponent;
}
class BorderDecorator extends Decorator {
public BorderDecorator(VisualComponent visualComponent) {
super(visualComponent);
}
@Override
public void draw() {
super.draw();
System.out.println("BorderDecorator.draw");
}
private void drawBorder(int val) {}
private int width;
}
class ScrollDecorator extends Decorator {
public ScrollDecorator(VisualComponent visualComponent) {
super(visualComponent);
}
@Override
public void draw() {
super.draw();
System.out.println("ScrollDecorator.draw");
}
private void scroll(int val) {}
private int top;
}
class Window {
public void setContent(VisualComponent visualComponent) {
this.visualComponent = visualComponent;
}
private VisualComponent visualComponent;
public VisualComponent getVisualComponent() {
return visualComponent;
}
}
class TextView extends VisualComponent{
}
public class DecoratorPattern {
public static void main(String[] args) {
Window window = new Window();
TextView textView = new TextView();
// // 일반 textView 를 사용할 경우
// window.setContent(textView);
//
// // border를 사용할 경우
// window.setContent(new BorderDecorator(textView));
// border와 스크롤을 사용할 경우
window.setContent(new BorderDecorator(new ScrollDecorator(textView)));
window.getVisualComponent().draw();
}
}
코드에서 보면 객체를 리턴받아 체인 형식으로 연결하는 것이 아닌 다형성을 활용해 Decorator 항목을 행동을 추가하는것을 볼수 있다.
Window는 VisualComponent 인터페이스를 통해 자신의 정보를 접근하기 때문에 장식자의 존재 자체를 알 수 없습니다.
장식자 패턴은 적응자 패턴과 관련이 있습니다. 즉 원래의 적응자는 인터페이스를 변경시켜 주는 것이지만, 장식자는 객체의 책임, 행동을 변화시킵니다.
복합체 패턴과도 관련이 됩니다. 한 구성요소만 갖는 복합체라고 볼수 있습니다, 객체의 합성이 아니라 새로운 행동을 추가
전략 패턴과도 관련이 됩니다. 장식자는 객체의 겉모양을 변경하고 전략은 객체의 내부를 변화시킵니다.
( 전략패턴 항목은 내부에 필드에 추가되는 항목으로 알고있음)
SOILD 항목에 OCP(Open-Closed-Principle, 계방폐쇠원칙) 항목에 부합한다.
소프트웨어 구성 요소(컴포넌트, 클래스, 모듈, 함수)나 확장에는 열려있고 변경에는 닫혀 있어야 한다.