티스토리 뷰

 

프록시 패턴이란?

 

대상 원본 객체를 대리(대신) 처리하게 함으로써 로직의 흐름을 제어하는 구조패턴입니다.

이 프록시를 통해서 크게 2가지인 접근 제어 (권한에 따른 접근 차단, 캐싱, 지연 로딩) , 부가 기능 추가 일을 할 수 있습니다.

 

 

 

프록시 패턴 vs 데코레이션 패턴

 

두 패턴 모두 둘 다 프록시를 사용한다는 공통점이 있지만 이 둘의 의도(intent)에 따라서 구분됩니다.

이번 배울 프록시 패턴은 접근 제어가 목적이며 데코레이터 새로운 기능, 부가 기능 추가가 목적입니다.

 

 

 

 

 

프록시 패턴의 구성요소

 

프록시 패턴은 다음과 같은 구성요소로 이루어져 있습니다.

 

  • 실제 주체 (Real Subject) : 원본 대상 객체
  • 주체 (Subject) : Proxy와 RealSubject를 하나로 묶는 인터페이스
  • 프록시 (Proxy) : 클라이어트와 Real Subject 사이에서 중재 역할을 수행하는 객체
  • 클라이언트 (Client) : 프록시 패턴을 사용하는 주체로, 프록시를 통해 RealSubject에 접근

 

프록시 패턴 클래스 의존 관계
그림1 프록시 패턴 클래스 의존 관계

 

 

기본 구조 코드

@Slf4j
public class Proxy implements Subject {

    
    private Subject target;	// Proxy 입장에서 내가 호출해야 되는 대상을 Target이라고 한다.
    private Object cacheData;

    public Proxy(Subject target) {
        this.target = target;
    }

    @Override
    public Object operation() {
        log.info("프록시 호출");
        if(cacheData == null){
            cacheData = target.operation();
        }
        return cacheData;
    }
}


class Client {
    public static void main(String[] args) {
    	RealSubject sub = new RealSubject();
        Proxy proxy = new Proxy(sub);
        proxy.operation();

    }
}

 

 

 

 

 

예시 코드 이미지 트레이닝

 

  • 다형성을 이용해 ExternalAPI를 구현한 ExternalAPIProxy, RealExternalAPI를 정의합니다.
  • ExternalAPIProxy는 실행(런타임) 중에 호출 했던 데이터가 없으면 다시 직접 호출을 합니다.
  • 호출하면 데이터를 캐시 저장하여 성능을 끌어 올릴 수 있습니다.

프록시 패턴 코드
그림2 프록시 패턴 코드

 

 

 

 

 

 

예시 코드

 

코드가 길어서 더보기 처리하였습니다.

클라이언트의 호출 (Client)

더보기
public class WebClient {
    private ExternalAPI externalAPI;

    public WebClient() {
        this.externalAPI = new ExternalAPIProxy();
    }

    public String fetchDataFromAPI(String endpoint){
        return externalAPI.fetchData(endpoint);
    }
}

 

외부 API 호출 추상화 (Subject)

더보기
public interface ExternalAPI {
    String fetchData(String endpoint);
}

 

외부 API 호출 프록시 (Proxy)

더보기
@Slf4j
public class ExternalAPIProxy implements ExternalAPI {
    private RealExternalAPI realExternalAPI;
    @Override
    public String fetchData(String endpoint) {
        if(realExternalAPI == null){
            realExternalAPI = new RealExternalAPI();
            log.info("외부 API 통신한 데이터");
        }
        return realExternalAPI.fetchData(endpoint);
    }
}

 

구현한 외부 API 호출 (Real Subject)

더보기
@Slf4j
public class RealExternalAPI implements ExternalAPI {

    @Override
    public String fetchData(String endpoint) {
        return "ok";
    }
}

 

 

 

 

 

테스트 코드와 결과 

 

클라이언트는 호출하면 Proxy가 자동적으로 생성이 될 것이고,

클라이언트는 Real Subject인지 Proxy인지 절대 모르고 그냥 호출만 하면 된다는 것입니다.

@Test
void execute(){
    WebClient client = new WebClient();
    String data = client.fetchDataFromAPI("https://api.example.com/data");
    String data2 = client.fetchDataFromAPI("https://api.example.com/data");
    String data3 = client.fetchDataFromAPI("https://api.example.com/data");
    System.out.println("데이터 : " + data);
    System.out.println("데이터 : " + data2);
    System.out.println("데이터 : " + data3);
}

/** 출력 
    14:02:01.567 [Test worker] INFO ExternalAPIProxy -- 외부 API 통신한 데이터
    데이터 : ok
    데이터 : ok
    데이터 : ok
 */

 

 

감사합니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함