Design Patterns

[Design Patterns] Proxy

우라릭 2024. 3. 31. 00:26

 

 

목차

    개요

    내용

    요약

    어떤 객체의 접근을 제어하기 위한 객체를 제공하자.

    예시

    어떤 객체는 생성을 하기 위한 리소스가 매우 클 수 있습니다. 예를 들어, GUI 툴에서 모든 그림들을 프로그램 실행 시에 다 로딩한다면 실행 시간이 매우 오래 걸리겠죠. 이럴 때 쓸 수있는 것이 프록시 패턴입니다.

    프록시 패턴은 기존 객체의 자리를 프록시라는 객체로 대체하는 패턴입니다. 이 프록시 객체는 기존 객체를 바로 가지지 않고 사용하는 쪽에서 필요로 할 때 비로소 객체를 생성합니다.

     

    구조

    이야깃거리

    언제 써야 할까?

    프록시 패턴은 기존 객체를 감싸면서 새로운 동작을 추가하는데에도 쓰일 수 있습니다. 아래의 다양한 프록시 종류를 참고해주세요.

    • Remote Proxy - 다른 곳에 있는 객체를 대체하는 로컬 객체입니다. 예를 들어, Github API를 사용하기 위해 GithubClient라는 클래스를 만들었다고 생각해봅시다. 이 클래스의 객체는 깃헙 서버에 있는 객체를 대체하는 로컬 객체라고 생각할 수 있을 것입니다.
    • Virtual Proxy - 값비싼 객체를 필요할 때 생성하게 해주는 객체입니다. 위 예시에서 보이는 ImageProxy가 그 예시입니다.
    • Protection Proxy - 기존 객체에 접근 권한을 관리하는 객체입니다. 권한에 따라 접근 권한을 다르게 해야 하는 authorization 작업을 할 때 쓰일 수 있습니다.
    • Smart Reference - 단순한 포인터 이상의 역할을 하는 프록시 객체입니다. 아래와 같은 행동을 추가로 해줄 수 있습니다.
      • 처음 요청할 때 DB에 있는 객체를 메모리로 가져오기
      • 객체를 가져오기 전에 락이 걸려있는지 확인한 후 가져오기
      • 등등

    장단점

    • (Pros) 서비스가 준비되기 위해 값비싼 객체가 초기화될 때까지 기다릴 필요가 없습니다.
    • (Pros) 객체에 여러 추가 연산을 제공해줍니다.
    • (Cons) Virtual proxy를 사용한다면 첫 번째 요청 때 응답 시간이 길 수 있습니다.
    • (Cons) 너무 많은 객체를 추가한다면 프로그램이 복잡해질 수 있습니다.

    Case Study

    Case 1. Spring @Transactional

    자바의 스프링 프레임워크는 Transactional이라는 어노테이션을 제공해줍니다. 이 어노테이션을 메소드에 붙이면 AOP 기술을 이용해서 해당 메소드를 호출하기 전에 트랜잭션과 관련된 작업을 추가해주는 객체를 프록시로 붙입니다.

    더 관심있으신 분은 org.springframework.transaction.interceptor.TransactionInterceptor 클래스를 살펴보세요

    출처

    GoF Design Patterns