프록시 패턴이란?
프록시는 “대리”라는 의미를 가진다. 그렇다면 무엇을 대리하는 것일까?
실제 객체의 ‘존재’를 대신한다. 실제 객체로 접근하기 전에 일단 프록시 객체를 거쳐가게끔 하는 방식이다.

구현 방식
- 프록시 객체는 실제 객체와 완벽히 같은 인터페이스를 구현하여야 한다. 그래야 다형성을 통해 프록시 객체가 실제 객체의 존재를 대신할 수 있다.
- 일단 동작을 위해 실제 객체의 존재를 대신하여 프록시 객체를 생성하여 메모리 상에 올려 놓는다. 이때, 프록시 객체는 실제 객체의 참조값을 갖고 있다.
- 실제 객체에 대한 요청이 들어오면 그때, 요청을 받은 프록시 객체가 실제 객체를 생성한다.
- 실제 객체가 로직을 실행합니다.
- 한번 실제 객체가 생성이 되었다면, 프록시 객체는 생성되어있는 실제 객체를 호출해줍니다.
public interface Subject { void doRequest(); }
public class RealSubject implements Subject { private String subjectName; public RealSubject(String subjectName) { this.subjectName = subjectName; } @Override void doRequest() { System.out.println("실제 객체를 통한 요청 실행"); } }
public class ProxySubject implements Subject { private String subjectName; private RealSubject realSubject; public ProxySubject(String subjectName) { this.subjectName = subjectName; } @Override void doRequest() { if(realSubject == null) { realSubject = new RealSubject(subjectName); } System.out.println("실제 객체를 통한 요청 전"); realSubject.doRequest(); System.out.println("실제 객체를 통한 요청 후"); } }
프록시 패턴은 어떤 문제점을 해결하려고 사용할까?
실제 객체를 사용하면 되는데 왜 굳이 프록시 객체를 한번 더 거쳐가게 만들까?
- 실제 객체로의 접근에 대한 제어가 필요한 경우
- 실제 객체의 생성을 지연하고 싶은 경우
- 만약 A라는 객체가 B객체를 가지고 있는 경우, A객체를 불러올 때, B객체도 필요합니다.다만, 현재 B객체에 대한 정보가 필요하지 않은 상황인데도 불러와야한다면 불필요한 자원 낭비가 일어나는 거겠죠. 그럴 경우 B객체의 존재를 대신하는 B프록시 객체를 만들어서 대신하고 있다가, 실제로 B객체가 필요할 경우에 B프록시 객체를 호출하여 B실제 객체를 생성합니다.
- 실제 객체를 호출하기 전후에 작업이 필요할 때
- 프록시 객체가 실제 객체를 생성, 호출하기 전후에 특정 로직을 추가할 수 있습니다. 예를 들자면, 실제 객체를 호출하기 전 과정에서 필터링(?) 로직을 적용하면 특정 클라이언트만 실제 객체로의 접근을 허용할 수 있습니다.
장단점
장점
- 새롭게 기능을 추가하려 할 때, 클라이언트나 실제 객체와 관련된 코드를 변경하지 않아도 된다.
- 프록시 객체를 통해 클라이언트의 요청이 실제 객체한테 가기 전후로 기능을 추가할 수 있는데, 클라이언트는 본인이 요청하는 곳이 프록시인지 실제 객체인지 모르기에 코드 변경이 없다. 실제 객체 관련한 코드도 변경할 필요가 없다.
단점
- 실제 객체 접근까지 한 단계를 더 거치므로 요청이 자주 있다면, 성능이 떨어질 수 있다.