@Slf4j
public class ConcreteLogic {
public String operation() {
log.info("ConcreteLogic 실행");
return "data";
}
}
public class ConcreteClient {
private ConcreteLogic concreteLogic;
public ConcreteClient(ConcreteLogic concreteLogic) {
this.concreteLogic = concreteLogic;
}
public void execute() {
concreteLogic.operation();
}
}
@Slf4j
public class TimeProxy extends ConcreteLogic {
private ConcreteLogic concreteLogic;
public TimeProxy(ConcreteLogic concreteLogic) {
this.concreteLogic = concreteLogic;
}
@Override
public String operation() {
log.info("TimeDecorator 실행");
long startTime = System.currentTimeMillis();
String result = concreteLogic.operation();
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("TimeDecorator 종료 resultTime={}ms", resultTime);
return result;
}
}
public class ConcreteProxyTest {
@Test
void noProxy() {
ConcreteLogic concreteLogic = new ConcreteLogic();
ConcreteClient client = new ConcreteClient(concreteLogic);
client.execute();
}
@Test
void addProxy() {
ConcreteLogic concreteLogic = new ConcreteLogic();
TimeProxy timeProxy = new TimeProxy(concreteLogic);
ConcreteClient client = new ConcreteClient(timeProxy);
client.execute();
}
}
- ConcreteLogic을 상속받아 TimeProxy를 만든다. client는 TimeProxy를 주입받고 TimeProxy가 ConcreteLogic을 주입받는다. client는 ConcreteLogic을 주입받지만 부모이기 때문에 자식인 TimeProxy를 주입받을 수 있다.
※ 인터페이스 기반이 더 좋을 수 있다. 왜나하면 상속에 구애 받지 않기 때문이다. 하지만 변경될 일이 거의 없는 경우에는 구체 클래스 기반이 더 좋을수도 있다. 하지만 인터페이스 기반과 구체 클래스 기반의 전체적인 문제는 프록시를 적용하고 싶은 만큼 클래스를 만들어야 한다는 문제점이 있다. 그래서 이것을 해결하는 방법으로 동적 프록시가 있다.
'개발이 좋아서 > Spring이 좋아서' 카테고리의 다른 글
프록시 팩토리 (0) | 2024.12.30 |
---|---|
JDK 동적 프록시, CGLIB (0) | 2024.12.30 |
프록시 - 프록시 패턴(기능 추가) (0) | 2024.12.30 |
프록시 - 프록시 패턴(접근 제어) (0) | 2024.12.30 |
디자인 패턴 - 전략 패턴(템플릿 콜백 패턴) (0) | 2024.12.29 |