프록시는 대리자이다.
대리자는 위와 같이 중간에서 다양한 일을 할 수 있다.
서버와 같은 인터페이스를 구현(혹은 서버 클래스를 상속)하여 클라이언트가 프록시를 호출하고, 프록시가 타겟 서버를 호출한다.
프록시 패턴 : 접근 제어를 위해 대리자를 제공
데코레이터 패턴 : 객체에 기능을 동적으로 추가, 기능 확장을 위해 대리자 제공
GOF 디자인 패턴에 따르면 의도에 따라 프록시, 데코레이터 패턴을 구분한다.
class Client {
Subject subject;
public Client(Subject subject) {
this.subject = subject;
}
public void doSomething() {
subject.execute();
}
}
클라이언트 클래스이다.
interface Subject {
String execute();
}
서버 인터페이스이다.
class SubjectImpl implements Subject {
@Override
public String execute() {
print("구현체 호출");
sleep(1초);
return "문자열 반환";
}
}
서버 구현체 클래스이다.
호출될 때 마다 1초가 소요된다.
class SubjectProxy implements Subject {
Subject subject;
String cacheString;
@Override
public String execute() {
print("프록시 호출");
if (cacheString == null) {
cacheString = subject.execute();
}
return cacheString;
}
}
프록시 구현체 클래스이다. 캐싱을 통해 접근 제어를 수행한다.
void run() {
Subject server = new SubjectImpl();
Subject proxy = new SubjectProxy(server);
Client client = new Client(proxy);
client.doSomething();
client.doSomething();
client.doSomething();
}
프록시 호출
구현체 호출
프록시 호출
프록시 호출
프록시를 통해 구현체가 한 번만 호출된다. 따라서 3초가 소요될 것이 1초만 소요된다.
클라이언트는 실제 객체가 주입된건지, 프록시가 주입된건지 알 수 없다.