본문 바로가기

Coding Note

[Design pattern] Proxy

Proxy pattern : 진짜 객체에의 접근을 대리자(proxy)를 통해 이루어 주므로서 객체의 기능에 제어를 할 수 있도록 해주는 패턴. 목적에 따라 여러가지 프록시로 나뉜다.


오브젝트 생성을 위한 비용이 크지만 이 오브젝트의 작은 부분(보통은 메소드)만이 자주 사용되는 클래스의 경우, 같은 인터페이스를 상속하는 대리자(proxy)를 통해 적은 비용으로 같은 역할을 할 수 있다. 정말로 큰 부분이 사용된다면, 그때 원래의 오브젝트를 생성해도 늦지않는다. 이러한 프록시를 virtual proxy라 한다.


진짜 객체에의 접근에 제한을 둬야할때도 있다. 다 같은 객체가 아니기 때문에 기능에는 차이가 있을 수 있으나 클라이언트 측에서는 이러한 사항을 따로 처리하기란 쉽지않은 일이다. 그러므로 대리자를 통해 접근 가능한 상황인지를 파악하여 접근에 제어를 할 수 있다. 이러한 프록시를 protection proxy라 한다.


remote proxy라 하여 원격지의 공간에 있는 객체에 대해서 원격지에 있지 않은것처럼 다룰 수 있게 인터페이스를 통합시켜주는 프록시도 있다. 네트워크 개념의 프록시는 remote proxy모델에 가깝다.


c++와 같은 낮은 수준의 언어에 대해서 원시포인터에 대한 안전한 관리를 위해 스마트포인터를 두고, 실제 주소공간에 대해 이 스마트 포인터를 통해 접근하도록 한다. 이러한 개념도 프록시이며 smart reference proxy라 한다.



- Virtual proxy

주로 메모리로의 로드에 비용이 크지만, 언제나 메모리에 있어야 할 필요는 없는 객체에 대해서 적용된다.

이미지뷰어는 보여질 이미지를 관리하기 위해 이미지 리스트를 메모리에 갖고있을 수 있다. 하지만 유저가 모든 이미지를 보는것은 아니다. 그럼에도 경로에 존재하는 모든 이미지를 메모리에 로드하여 관리한다면, 자원의 낭비가 심할것이다.


절차지향적으로 생각한다면, 이미지에 접근할 수 있는 키의 리스트(예를들어 이미지의 경로)만을 메모리에 올려두고 이미지의 디스플레이 요청이 있을때 이미지가 로드되어있지 않다면 그때 찾아열 수 있을것이다. 


하지만 이미지의 뷰 요청때마다 이미지의 로드 여부 확인과 객체의 생성 두 작업이 동반되며 이미지 뷰 메커니즘이 외부로 드러나버린다.

이런 상황을 virtual proxy 구조를 통해 해결할 수 있다. 동일한 인터페이스를 대해 '진짜'와 '대리자'가 동일하게 구현하며 '대리자'는 '진짜'를 가지고 구현된다. 


VirtualProxy에 대해서 연산을 하지만, 직접적으로 RealSubject 가 필요하게된다면 그제서야 객체를 생성한다. Lazy initialize의 한 예이다. 이런 구조라면 정말로 RealSubject가 필요한 상황이 아니라면 인스턴스는 생성되지 않는다.


- Protection proxy

동일한 인터페이스를 가지는 객체라 해도 동일하게 다뤄질 수 있는건 아니다. 그럼에도 동일한 인터페이스를 가지기 때문에 동일하게 다뤄지길 바란다. 이러한 상황에 protection proxy를 통해 제어할 수 있다



예외상황에 대한 판단을 ProtectionProxy에게 넘김으로서 Client는 예외의 발생에 대해서만 관리하면 된다. 클래스 구조의 접근지정자와는 다른개념의 접근 제어라 할 수 있다는 점에서 의미가있다.


- Remote proxy

원격지의 객체에 대해서 접근을 제어하지만, 클라이언트의 입장에선 원격지의 객체인지, 로컬의 객체인지 신경쓰지 않아도 된다. 


클라이언트는 Subject에 대해서만 접근하기 때문에 두가지 객체의 doOperation메소드에 대한 구현상의 차이를 구별할 수 없다.


Subject firstSubject = new RealSubject();

Subject secondSubject = new RemoteProxy();


firstSubject.doOperation();

secondSubject.doOperation(); //firstSubject와 달리 원격지의 데이터에 대한 기능을 수행한다.



한줄요약 : 객체에의 접근에 제어가 필요하다면 대신맨을 부르자

'Coding Note' 카테고리의 다른 글

[Design pattern] Mediator  (0) 2013.03.25
[Design pattern] Interpreter  (0) 2013.03.18
[Design pattern] Flyweight  (3) 2013.03.05
[Design pattern] Facade  (0) 2013.03.04
[Design pattern] Decorator  (0) 2013.03.03