프록시는 대리인이라는 의미를 갖고있다. 따라서 프록시 패턴이란, 원본 객체의 일을 대신 처리하여 로직의 흐름을 제어 하는 행동 패턴이다
이름에서 볼 수 있듯이 클라이언트는 원본객체를 직접 사용하는 것이 아닌 프록시를 거쳐서 사용하는 패턴이다.
프록시에서 추가적인 로직을 처리한뒤 원본 객체에 접근하게 된다.
왜 번거롭게 대리 객체를 통해서 사용하나?
대리 객체를 사용해서 얻을 수 있는 기능
- 보안 : 원본 객체에 접근할 수 있는 권한이 있는지 확인
- 캐싱 : 굳이 원본객체 까지 가지 않고 프록시에 데이터가 남아있다면 빠른 진행
- 유효성 검사 : 원본객체에 넘겨줄 데이터가 올바른지 검사
- 지연 초기화 : 대상의 생성 비용이 비싸면 프록시를 통해 그것을 필요로 할때까지 연기할 수 있다.
- 로깅 : 프록시를 통해 원본 객체 사용을 기록
- 원격 객체 : 원격에 있는 객체를 로컬처럼 보이게 한다.
구조

- RealSubject : 실제 객체
- Proxy : 프록시 객체
- Subject : 실제 객체와 프록시 객체를 하나로 묶는 인터페이스
종류
- 기본형 프록시
- 기본적인 프록시 패턴
- 프록시 객체가 실체 객체를 갖고있고 프록시 객체를 통해 실체 객체의 메서드를 실행
- 가상 프록시
- 생성 지연 초기화 방식
- 실제 객체를 갖고있는 프록시 객체를 설계, 이때 실제 객체를 생성하지 않고 멤버로만 소유
- 프록시의 메서드가 호출되었을때에 메서드내에서 실제 객체를 생성하고 실제 객체의 메서드를 실행
- 생성 비용이 비싼 실제 객체를 진짜 필요로 할때에 메모리에 올릴 수 있다.
- 보호 프록시
- 실제 객체를 보유하고 있는 프록시 객체 구현
- 프록시의 메서드를 실제 객체의 메서드를 실행하도록 구현하고 이전에 조건문을 통해 접근 여부를 판단
- 로깅 프록시
- 이전과 같은 흐름으로 구성되고 메서드 시작과 끝에 로깅을 추가
- 원격 프록시
- 원격 서버에 있는 객체를 사용하기 위해서는 네트워크와 관련된 복잡한 작업들이 필요하다
- 이 복잡한 과정은 프록시 객체가 처리하고 결과값만 반환
- 클라이언트는 프록시 객체만 사용하기에 편리하게 원격 서버에 있는 객체를 사용
- 캐싱 프록시
- 실제 객체를 사용할때 데이터가 큰 경우 프록시 객체에 캐싱하여 재사용의 효율을 높임
- 클라이언트의 요청을 프록시 객체를 통해 캐싱하고 캐시의 수명을 관리
사용 시기
- 객체의 접근을 제어하거나 기능을 추가하고 싶은데, 기존의 객체를 수정할 수 없을때
- 초기화 지연, 접근 제어, 로깅, 캐싱 등의 기능을 별도의 수정없이 사용하고 싶을때
장점
- 개방 패쇄 원칙 준수
- 단일 책임 원칙 준수 -> 원본 객체는 기능에 집중 프록시 객체가 부가 기능 수행
- 클라이언트는 프록시 객체를 통해 서비스 사용, 원본 객체의 내부 정보 보호
단점
- 코드의 복잡도 증가
- 프록시의 기능이 많아진다면 응답이 오래걸림