본문 바로가기
GoF

프록시 패턴

by jisung-kim 2023. 7. 24.

 

Client와 Server 개념에서 일반적으로는 Client에서 Server를 직접 호출하는 경우가 일반적이다

프록시 패턴은  Client가 Server를 직접 호출하지 않고 중간에 Proxy(간접호출)을 두고 Proxy가 Server를 호출하는 방식이다

Client -> Proxy -> Server

Client -> Proxy1 -> Proxy2 -> Server


주의사항

객체에서 Proxy가 되려면, Client는 Server에게 요청을 한 것인지, Proxy에게 요청을 한것인지 조차 몰라야한다.

Server와 Proxy는 같은 인터페이스를 사용해야한다.

그리고 Client가 사용하는 Server 객체를 프록시 객체로 변경해도 Client 코드를 변경하지 않고 작성이 가능해야한다.


프록시의 주요 기능

- 접근제어 : 권한에 따른 접근 차단, 캐싱, 지연로딩

- 부가 기능 추가: 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행한다. 

ex) 요청값이나, 응답 값을 중간에서 변형,  실행 시간을 측정해서 추가 로그를남긴다.

 


Subject Interface

public interface Subject {

    String operation();
}

 

Subject 인터페이스를 구현한 CacheProxy클래스

@Slf4j
public class CacheProxy implements Subject{

    private Subject target;
    private String cacheValue;

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

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

Client가 프록시를 호출하면 프록시가 최종적으로 실제 객체를 호출해야한다. 따라서 내부에 실제 객체의 참조를 가지고 있어야 한다.

cacheValue 변수가 null일경우에만 Subject(target)를 호출해 값을 가져온다.

cacheValue의 값이 null이 아닐경우 빠르게 응답 가능.

 

Subject를 요청하는 Client클래스

public class ProxyPatternClient {

    private Subject subject;

    public ProxyPatternClient(Subject subject){
        this.subject = subject;
    }

    public void execute(){
        subject.operation();
    }
}

 

ProxyPatternClient 클래스를 호출하는 테스트 코드

    @Test
    void cacheProxyTest() {
        RealSubject realSubject = new RealSubject();
        CacheProxy cacheProxy = new CacheProxy(realSubject);
        ProxyPatternClient client = new ProxyPatternClient(cacheProxy);

        client.execute();
        client.execute();
        client.execute();

    }