Proxy (대리인)
- 행위(책임)를 대신 수행해주는 대리인
- 프록시를 사용하는 이유
- 객체의 제일 중요한 책임만 남겨둘 수 있음
- 책임을 분리할 수 있으므로 OCP 성립 (객체의 원래 책임을 수정하지 않음)

프록시 패턴의 장단점
장점
- 객체의 사이즈가 커서 로딩되기 전에도 참조 가능
- 인터페이스를 통해 메서드를 숨기면서 노출 가능
- 떨어져 있는 객체도 사용 가능
- 객체의 접근에 대한 사전 처리 가능
단점
- 객체 생성 시 단계가 늘어나므로 빈번한 객체 생성 시 성능 저하
- 프록시 내부에서 스레드가 생성, 동기화가 필요한 경우 성능 저하
- 로직이 난해해져 가독성 저하
Q. 문지기의 역할을 추가하려면?
- 기존의 역할은 들어오는 동물을 쫓아내기
- 쫓아내기 전, 동물들에게 인사를 하고 싶음
- Doorman의 코드를 추가하거나 변경할 수 없음 (OCP 위반)
A : 프록시를 새로 제작
- 두 가지 방법이 존재
- has 관계를 통한 DI 사용 (컴퍼지션)
public class DoormanProxy {
// Composition (DI)
private Doorman doorman; // has
public DoormanProxy(Doorman doorman) {
this.doorman = doorman;
}
public void 쫓아내(Animal animal) {
System.out.println("안녕");
doorman.쫓아내(animal);
}
}
public class App {
public static void main(String[] args) {
// 1. init
Mouse m1 = new Mouse();
Doorman d1 = new Doorman();
Cat c1 = new Cat();
DoormanProxy dp = new DoormanProxy(d1);
// 2. run
dp.쫓아내(m1);
dp.쫓아내(c1);
}
}
- extends 사용 (비권장)
- 비즈니스의 문제 (DoormanProxy는 Doorman인가?)
public class DoormanProxy extends Doorman{
public void 쫓아내(Animal animal) {
System.out.println("안녕");
super.쫓아내(animal);
}
}
public class App {
public static void main(String[] args) {
// 1. init
Mouse m1 = new Mouse();
Cat c1 = new Cat();
DoormanProxy dp = new DoormanProxy();
// 2. run
dp.쫓아내(m1);
dp.쫓아내(c1);
}
}

프록시 패턴 사용 예시
- 원격 프록시 : 원격 서버에 있는 객체에 접근 (네트워크 통신 등 처리) → 스트리밍 등
- 가상 프록시 : 객체를 지연 로딩 → 고해상도 이미지 로딩하면서 썸네일 보여주기 등
- 보호 프록시 : 객체에 대한 접근 권한 제어 → 프록시를 통한 사용자의 권한 체크
- 로깅 프록시 : 객체에 대한 접근 기록 → DB 로깅
- 캐싱 프록시 : 객체의 결과를 캐싱하여 응답 시간 단축 → 자주 요청되는 데이터 결과 캐싱 등
Share article