프록시 패턴 : https://velog.io/@yjw8459/Proxy-Pattern
기존에 있는 것을 꾸미다, 추가한다는 의미의 데코레이터 패턴은 프록시 패턴과 굉장히 유사하고, 상황에 따라서는 같은 경우도 있다.
디자인 패턴에서 중요한 것은 해당 패턴의 겉모양이 아니라 그 패턴을 만든 의도가 더 중요한데, 프록시 패턴과 데코레이터 패턴은 의도로 구분한다.
데코레이터 패턴과 프록시 패턴의 구분 정리
프록시를 사용하고 해당 프록시가 접근 제어가 목적이라면 프록시 패턴이고, 새로운 기능을 추가하는 것이 목적이라면 데코레이터 패턴이 된다.
런타임 객체 의존 관계
//Server Interface
public interface Component {
String operation();
}
//Server
@Slf4j
public class RealComponent implements Component{
@Override
public String operation() {
log.info("RealComponent 실행");
return "data";
}
}
//Client
@Slf4j
public class DecoratorPatternClient {
private Component component;
public DecoratorPatternClient(Component component) {
this.component = component;
}
public void execute(){
String result = component.operation();
log.info("result={}", result);
}
}
/**
* Client -> RealComponent 의존관계 설정
*/
@Test
void noDecorator(){
Component realComponent = new RealComponent();
DecoratorPatternClient client = new DecoratorPatternClient(realComponent);
client.execute();
}
데코레이터 패턴 적용 전 Client -> RealComponent
의존 관계이다.
//Decorator
@Slf4j
public class MessageDecorator implements Component{
private Component component;
public MessageDecorator(Component component) {
this.component = component;
}
@Override
public String operation(){
log.info("MessageDecorator 실행");
String result = component.operation();
//result -> *****data*****
String decoResult = "*****" + result + "*****";
log.info("MessageDecorator 꾸미기 적용 전 = {}, 적용 후={}", result, decoResult);
return decoResult;
}
}
/**
* Client -> MessageDecorator -> RealComponent
*/
@Test
void decorator1(){
Component realComponent = new RealComponent();
Component messageDecorator = new MessageDecorator(realComponent);
DecoratorPatternClient client = new DecoratorPatternClient(messageDecorator);
client.execute();
}
Client에 messageDecorator를 주입하면서
Client -> MessageDecorator -> RealComponent
의존 관계로 설정한다.
데코레이터 패턴은 클라이언트와 서버를 변경하지 않고, 여러 부가 기능으로 꾸미는 것이 특징이다.
런타임 객체 의존 관계
TimeDecorator
@Slf4j
public class TimeDecorator implements Component{
private Component component;
public TimeDecorator(Component component) {
this.component = component;
}
/**
* 실행시간 측정 부가 기능
* @return
*/
@Override
public String operation() {
log.info("TimeDecorator 실행");
long startTime = System.currentTimeMillis();
String result = component.operation();
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("TimeDecorator 종료 resultTome={}ms", resultTime);
return result;
}
}
/**
* Client -> TimeDecorator -> MessageDecorator -> RealComponent
*/
@Test
void decorator2(){
Component realComponent = new RealComponent();
Component messageDecorator = new MessageDecorator(realComponent);
Component timeDecorator = new TimeDecorator(messageDecorator);
DecoratorPatternClient client = new DecoratorPatternClient(timeDecorator);
client.execute();
}
Client에 TimeDecorator를 주입하고, TimeDecorator는 MessageDecorator를 의존하면서
Client -> TimeDecorator -> MessageDecorator -> RealComponent
의존 관계로 설정한다.