구조 (3) - 데코레이터(Decorator) 패턴
- 객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 해주는 패턴
-
부가기능 추가
- 프록시 패턴과 데코레이터 패턴은 모양이 거의 같다. 의도에 따라 패턴을 구분할 수 있다.
- 프록시 : 접근을 제어 하기 위한 프록시 제공
- 데코레이터 : 부가 기능을 동적으로 추가하고 기능 확장을 위한 유연한 대안 제공
구현
- interface
public interface Component {
String request();
}
- RealComponent
- 실제로 꾸며지는 타켓 객체
public class RealComponent implements Component {
@Override
public String request() {
return "Hello World!";
}
}
- Decorator (추상클래스)
- RealComponent 구현하고 있는 interface를 구현한다
- 필드에 Component를 갖고 있음
public abstract class Decorator implements Component {
private final Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public String request() {
return component.request();
}
}
- Concrete Decorator
public class MessageDecorator extends Decorator {
public MessageDecorator(Component component) {
super(component);
}
@Override
public String request() {
String result = component.request();
return "***" + result + "***";
}
}
public class TimeDecorator extends Decorator {
public TimeDecorator(Component component) {
super(component);
}
@Override
public String request() {
long startTime = System.currentTimeMillis();
String result = component.request();
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
return result;
}
}
- Client(Main 메서드)
- 데코레이터 객체를 통해 실행한다
public class Main {
public static void main(String[] args) {
Component realComponent = new RealComponent();
Component messageDecorator = new MessageDecorator(realComponent);
Component timeDecorator = new TimeDecorator(messageDecorator);
System.out.println(timeDecorator.request()); // time + message
}
}
- 의존관계
Client --> TimeDecorator --> MessageDecorator --> RealComponent
장점
- 기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있다 [OCP]
단점
- 코드의 복잡도가 증가한다