구조 (2) - 프록시(Proxy) 패턴
- 특정 객체에 대한 접근을 제어하거나 기능을 추가할 수 있는 패턴
- 특정 객체를 접근하기 전에 프록시 객체를 먼저 접근해야 한다 (like 비서)
- 흐름제어만 할 뿐 결과값을 조작하거나 변경시켜서는 안된다
- 기능
- 접근 제어 : 권한에 따른 접근 차단, 캐싱, 지연 로딩
프록시 패턴
- 부가기능 추가
데코레이터 패턴
- 접근 제어 : 권한에 따른 접근 차단, 캐싱, 지연 로딩
- 프록시 패턴과 데코레이터 패턴은 모양이 거의 같다. 의도에 따라 패턴을 구분할 수 있다.
- 프록시 : 접근을 제어 하기 위한 프록시 제공
- 데코레이터 : 부가 기능을 동적으로 추가하고 기능 확장을 위한 유연한 대안 제공
- 클라이언트(Client)가 어떤 요청을 하면(RealSubject의
DoAction()
) 프록시가 대신 RealSubject의DoAction()
을 호출하고 반환 값은 클라이언트에게 반환한다 - 클라이언트는 프록시에게 요청한 것인지 실제객체에게 요청한 것인지 모른다
구현
- interface
public interface Subject {
String request();
}
- RealSubject
public class RealSubject implements Subject {
@Override
public String request() {
return "Hello World!";
}
}
- Proxy
- RealObject가 구현하고 있는 interface를 구현한다
- 필드에 RealObject를 갖고 있음
public class Proxy implements Subject {
private final Subject target = new RealSubject();
private String cacheValue;
@Override
public String request() {
System.out.println("Proxy work");
if (cacheValue == null) { // 캐싱
cacheValue = target.request();
}
return cacheValue;
}
}
- Client(Main 메서드)
- 프록시 객체를 통해 실행한다
public class Main {
public static void main(String[] args) {
Subject subject = new Proxy();
System.out.println(subject.request());
}
장점
- 기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있다 [OCP]
- 생성비용이 큰 객체를 구동시 생성하지 않고 실제 사용시 생성시킬 수 있다(초기화 지연)
- 접근을 제어할 수 있다
단점
- 코드의 복잡도가 증가한다