프록시 패턴

이종찬·2023년 2월 6일
0
post-custom-banner

📖프록시 패턴?

Proxy는 대리인 이라는 뜻으로, 뭔가 대신해서 처리하는 것입니다. Proxy Class를 통해 대신 전달 하는 형태로 설계가 됩니다. 실제 Client는 Proxy로 부터 결과를 받습니다. 구체적으로 인터페이스를 사용하고 실행시킬 클래스에 대한 객체가 들어갈 자리에 대리자 객체를 대신 투입합니다. 클라이언트 쪽에서 실제와 대리자 중 어느 객체를 투입했는지 모르게 처리하는 것입니다. SOLID중에서 개방 폐쇄 원칙, 의존 역전 원칙을 따릅니다.

proxy 특징

  • 실제 서비스와 같은 이름의 메서드를 구현한다.
  • 실제 서비스에 대한 참조 변수를 가진다.
  • 실제 서비스와 같은 이름을 가진 메서드를 호출하고 해당 값을 클라이언트에게 준다.
  • 실제 서비스의 메서드 호출 전후에 별도 로직을 수행할 수도 있다. -> ex) 서비스의 실행 속도 측정

🤔 사용해야 하는 이유는?

어떤 객체를 사용하려고 할 경우, 직접적 참조가 아닌 대리자 객체를 통해 대상 객체에 접근하게 되면 해당 객체가 메모리에 존재하지 않아도 기본적인 정보를 참조,설정 할 수 있으며 실질적 객체의 기능이 필요한 시점까지 해당 객체의 생성을 미룰 수 있습니다. 즉, 기존 객체의 리소스가 무거울 경우 이러한 캐싱 과정을 통해 부하를 줄일수 있습니다.

😮 사용되는 사례

가상 프록시

해당 객체가 생성된 것 처럼 동작하도록 만들고 싶을 때 사용합니다. -> 호출 직전까지 객체 생성을 연기합니다.

리소스가 많이 요구되는 작업들이 필요할 때 프록시 클래스에서 작은 단위의 작업을 처리하고 꼭 필요한 경우에만 주체 클래스를 사용하도록 구현됩니다. 또한 처음 요청 및 접근할 때만 실제 객체가 생성됩니다. 이후 프록시를 참조하여 실제 객체를 대신할 수 있습니다.

원격 프록시

원격 객체에 대한 대변자 역할을 하는 객체, 서로 다른 주소 공간에 있는 객체를 같은 주소 공간에 있는 것 처럼 동작하게 하는 패턴입니다. client -> proxy -> real subject 예를 들어 google docs처럼 브라우저는 브라우저대로 필요한 자원을 로컬에 가지고 있으며 또 다른 일부 자원은 Google 서버에 있는 형태입니다.

보호 프록시

주체 클래스에 대한 접근을 제어하거나, 객체마다 접근 권한을 다르게 하기 위해 사용됩니다. 프록시 클래스에서 클라이언트가 주체 클래스에 대한 접근을 허용 여부를 결정합니다. 주로 민감한 객체에 대해 접근을 제어하기 위해 사용됩니다.

✅ Proxy와 Adapter의 차이

둘다 클라이언트와 객체 사이에 위치하며, 클라이언트의 요청을 다른 객체에 전달해 주는 것은 맞습니다. 다른점은 어댑터 패턴의 경우 다른 객체의 인터페이스를 바꾸어주지만, 프록시 패턴에서는 동일한 인터페이스를 사용합니다.

🤔 문제가 되는 경우는?

  • 객체가 생성할 때 한단계를 거치게 됩니다. 즉, 빈번한 객체 생성의 경우 성능이 저하될 수 있습니다. 또한 객체 생성을 위해 스레드 생성 및 동기화가 구현되어야 하는 경우도 마찬가지 입니다.
  • 서로와 서로를 연결해주는 중간다리? 역할을 하는 클래스를 사용하므로써 로직이 난해해져 가독성이 떨어질 수 있습니다.

👨‍💻 구현

BrowserInterface

public interface BrowserInterface {
    public Html show();
}

BrowserProxy

class Browser implements BrowserInterface {
    private String url;

    public Browser(String url) {
        this.url = url;
    }

    @Override
    public Html show() {
        System.out.println("browser loading html from : " + url);
        return new Html(url);
    }
}

class BrowserProxy implements BrowserInterface {

    private String url;
    private Html html;

    public BrowserProxy(String url) {
        this.url = url;
    }

    @Override
    public Html show() {
        if (html == null) {
            this.html = new Html(url);
            System.out.println("browser proxy loading html from : " + url);
        }
        System.out.println("browser proxy use cache html :" + url);
        return html;
    }
}

public class Main {
    public static void main(String[] args) {
        BrowserInterface proxy = new BrowserProxy("www.naver.com");
        proxy.show();
        proxy.show();
        proxy.show();
        proxy.show();
    }
}

실행결과

browser proxy loading html from : www.naver.com
browser proxy use cache html :www.naver.com
browser proxy use cache html :www.naver.com
browser proxy use cache html :www.naver.com
browser proxy use cache html :www.naver.com

처음 실행을 제외하고는 proxy를 적용하므로써 caching된 결과만 나오는 것을 확인할 수 있다.

🙂 요약

  • proxy pattern은 객체를 직접적으로 참조하는 것이 아닌 대리자 객체를 통해 기능을 수행합니다.
  • proxy pattern은 메모리 낭비를 방지하며 데이터 공유 및 접근을 고려합니다.
  • proxy pattern에는 가상 프록시, 원격 프록시, 보호 프록시가 있습니다.
  • proxy pattern이 야기할 수 있는 문제는 코드 복잡도 증가, 성능 저하 입니다.
profile
왜? 라는 질문이 사라질 때까지
post-custom-banner

0개의 댓글