본문 바로가기

Design/Design Pattern

[Design Pattern] Proxy Pattern

이번 장에서는 프록시(Proxy) 패턴에 대해서 알아본다.
샘플 코드는 여기 (링크) 프로젝트의 테스트 코드로 정리해두었다.


프록시 패턴이란?
위키백과에 따른 정의는 아래와 같다.

일반적으로 프록시는 다른 무언가와 이어지는 인터페이스의 역할을 하는 클래스이다.
프록시는 어떠한 것(이를테면 네트워크 연결, 메모리 안의 커다란 객체, 파일, 또 복제할 수 없거나 수요가 많은 리소스)과도 인터페이스의 역할을 수행할 수 있다.

결국 어떠한 일을 수행하는 A라는 객체가 있을 때 클라이언트가 A 객체를 바로 참조하여 호출하는 것이 아니라
중간에 Proxy 객체를 두고 Proxy 객체를 통해서 참조하는 디자인 패턴이다.

프록시 패턴의 종류로는 아래와 같은 프록시들이 있다.

가상프록시: 객체의 생성을 연기하고 마치 객체가 생성된 것처럼 동작시키는 패턴이다. 대표적으로 JPA에서 사용된다.
원격프록시: 원격 저장소에 있는 객체에 대한 프록시로서 서로 다른 공간에 있는 객체에 대해 마치 같은 공간에 있는 것처럼 만드는 패턴이다. 대표적으로 Google 공유 문서에서 사용된다.
보호프록시: 어떠한 일을 수행하는 객체에 대한 접근을 제어하거나 객체마다 접근 권한을 달리하고 싶을 때 사용하는 패턴이다.

필자는 학생과 학생을 조회하는 선생님을 예로 설명해보도록 하겠다.
이번에 가상프록시와 보호프록시로 예시를 들어보도록 하겠다.


GoF Design Pattern에 따르면 아래와 같은 Class Diagram이 그려진다.

Subject: 구현체들이 구현해야하는 기능을 정의하고 있는 인터페이스.
RealSubject: Subject의 구현체.
Proxy: Client의 Subject 둘을 이어주는 역할을 하는 클래스.

위의 그림을 학생과 학생을 조회하는 선생님에 적용하면 아래와 같은 그림이 그려진다.

Teacher(선생님)은 School에게 학생 정보를 요청한다.
이 때 보호프록시인 ProxySchool를 통과해야한다. 실제 객체인 DefaultSchool의 getStudent는 name만 입력받지만
ProxySchool은 name과 함께 password도 같이 입력받는다.
즉, ProxySchool에서 비밀번호 검증 로직을 통과해야지만 실제 객체인 DefaultSchool에게 학생 정보를 요청할 수 있는 것이다.

다음으로 가상프록시인 ProxyStudent가 나온다.
ProxyStudent는 Student를 확장(상속)하고 있으며 필요할 때 슈퍼클래스의 정보를 초기화 시키는 역할을 한다.


자세한 내용은 코드를 통해서 살펴보도록 한다.

School Interface
학교들이 구현해야하는 메서드를 정의한 인터페이스
프록시 객체인 StudentProxy를 리턴하는 getProxyStudent 메서드만 있으면 되지만
프록시 객체를 사용할 때와 실제 객체를 사용할 때의 차이를 확인하기 위해 getOriginStudent 메서드도 정의하고 있다.

DefaultSchool Class
School Interface를 구현하고 있으며 프록시 학생 객체와 일반 학생 객체를 리턴하는 메서드를 구현하고 있다.

SchoolProxy Class
선생님들이 학생 정보를 요청하는 프록시 학교 객체다.
비밀번호 검증을 하고 통과한 요청에 대해서만 실제 객체를 통해 학생 정보를 반환하고 있다.
실제 객체인 DefaultSchool를 보호하는 보호프록시라는 점을 주의깊게 봐야한다.

Student Class
학생의 정보를 가지고 있는 클래스

StudentProxy Class
학생 객체를 감싸고 있는 학생 프록시 객체다.
주의깊게 봐야하는 부분은 성적표를 조회하는 getGrade1Report와 getGrade2Report다.
최초에 객체를 생성할 때 객체의 모든 값을 메모리에 올리는 것이 아니라 필요한 시점에 조회하여 메모리에 올린다는 점이다.
필요한 시점 이전에는 마치 값을 가지고 있는 것처럼 행동하다가 늦게 초기화하는 가상프록시의 역할을 하고 있다.

Database Class
StudentProxy가 필요한 시점에 성적표 정보를 초기화하기 위해 데이터를 조회하는 클래스
실제로 데이터베이스에서 정보를 조회하는 로직을 포함하고 있다고 생각하면 된다.

Teacher Class
SchoolProxy를 생성하고 이를 통해 학생정보를 조회하는 클래스.
보호프록시인 SchoolProxy에 의해 비밀번호가 틀린 경우 학생정보가 null인 것은 쉽게 이해가 될 것이다.

가상프록시 객체인 StudentProxy와 실제 객체인 Student의 차이를 잘 이해해야한다.
Student는 최초에 생성될 때 성적표 정보를 가지고 생성되지 않았다.
추후에 성적표 정보를 조회할 때 늦게 초기화 시켜주는 기능이 없기 때문에 null로 조회되는 것을 확인할 수 있다.
StudentProxy 또한 최초에 생성될 때 성적표 정보를 가지고 생성되지 않았다.
추후에 성적표 정보를 조회할 때 Database 클래스를 통해서 성적표 정보를 초기화시키고 조회하기 때문에 정보를 정상적으로 조회할 수 있다.
아마 JPA를 사용해 본 개발자라면 쉽게 이해할 수 있을 것이다.

코드를 실행시킨 결과는 아래와 같다.


지금까지 학생과 학생의 정보를 조회하는 선생님에 프록시 패턴을 적용하여 알아보았다.

'Design > Design Pattern' 카테고리의 다른 글

[Design Pattern] 정리  (0) 2022.02.08
[Design Pattern] Interpreter Pattern  (0) 2022.02.06
[Design Pattern] Command Pattern  (0) 2022.02.06
[Design Pattern] Iterator Pattern  (0) 2022.02.04
[Design Pattern] Flyweight Pattern  (0) 2022.02.04