본문 바로가기

디자인패턴

프록시 패턴

프록시

프록시(Proxy)는 기본적으로 어떤 다른 객체에 대한 인터페이스 역할을 하는 객체로, 원래 객체에 접근하는 요청을 중간에서 가로채 처리하거나 전달하는 역할을 한다.

프록시 패턴은 객체 지향 디자인 패턴 중 하나로, 중간에서 다양한 처리를 수행하거나 컨트롤이 필요한 상황에서 유용하게 사용된다. 프록시를 사용하면 원본 객체의 로직을 변경하지 않고도 해당 객체의 동작을 확장하거나 수정할 수 있어 유연성을 향상시킬 수 있다.

타입

  • Static Proxy
    • 컴파일 타임에 프록시 클래스가 정의된다.
    • 원본 객체와 동일한 인터페이스를 구현하는 별도의 프록시 클래스를 작성해야 한다.
  • Dynamic Proxy
    • 런타임에 프록시 객체가 동적으로 생성된다.
    • Java에서는 Proxy 클래스와 InvocationHandler 인터페이스를 사용하여 동적 프록시를 구현할 수 있다.

용도 및 유스케이스

  • Virtual Proxy
    • 실제 객체의 생성 비용이 높을 때 초기화를 지연시키기 위해 사용한다.
  • Remote Proxy
    • 원격 객체에 대한 로컬 인터페이스를 제공한다.
    • 예를 들면, RMI (Remote Method Invocation)에서 사용됩니다.
  • Protective Proxy
    • 원본 객체에 대한 접근 제어나 보안을 위해 사용된다.
  • Smart Proxy
    • 원본 객체에 접근할 때 추가적인 작업, 예를 들어 참조 카운팅이나 쓰레드 안전성 확보 등을 수행하기 위해 사용된다.

동작 방식

프록시는 원본 객체에 대한 참조를 유지하면서 클라이언트와의 상호 작용을 중재한다

클라이언트는 프록시를 원본 객체로 인식하고, 프록시에 요청을 보낸다.

프록시는 이 요청을 가로채 필요한 전처리를 수행한 후 원본 객체에 전달하며, 원본 객체의 응답을 받아 후처리를 수행한 후 클라이언트에 반환한다.

이미지 로딩 라이브러리에서 큰 이미지 파일을 처리할 때, 파일을 즉시 로드하는 대신에 프록시 객체를 사용하여 이미지 로딩을 지연시킬 수 있다. 사용자가 이미지를 실제로 볼 필요가 있을 때만 원본 이미지 객체를 생성하고 로드한다.

프록시 코드

인터페이스 정의

public interface Image {
    void display();
}

원래 서비스 구현

public class RealImage implements Image {

    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("Loading " + filename);
    }

    @Override
    public void display() {
        System.out.println("Displaying " + filename);
    }
}

프록시 구현

public class ProxyImage implements Image {

    private RealImage realImage;
    private String filename;

    public ProxyImage(String filename) {
        this.filename = filename;
    }

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

프록시 사용

public class ProxyPatternDemo {

    public static void main(String[] args) {
        Image image1 = new ProxyImage("testImage1.jpg");
        Image image2 = new ProxyImage("testImage2.jpg");

        // 이미지 로드가 여기서 발생합니다.
        image1.display(); 
        // 이미지가 이미 로드되었기 때문에, 다시 로드하지 않습니다.
        image1.display(); 

        // 이 이미지도 처음 호출시에 로드됩니다.
        image2.display();
    }
}

'디자인패턴' 카테고리의 다른 글

템플릿 메서드 패턴  (0) 2023.12.12
싱글턴 패턴  (0) 2023.04.12
의존 관계 제어  (0) 2022.08.24