프록시 패턴 (Proxy Pattern)

Bo Ram·2025년 4월 20일

1-1. 의도 (Intent)

프록시 패턴은 객체에 대한 접근을 제어하는 대리인을 제공하는 구조적 디자인 패턴임.
즉, 어떤 객체가 있을 때 그 객체를 직접 사용하지 않고, 대신 프록시 객체를 통해 접근하게 함으로써,
접근 제어, 지연 로딩, 권한 제어, 원격 접근 등 부가적인 책임을 수행할 수 있게 함.


1-2. 문제 상황

어떤 이미지 뷰어 프로그램이 있고, 사용자가 그림을 클릭하면 큰 이미지가 뜨게 되어 있음.
하지만 이미지를 불러오는 데 시간이 오래 걸리기 때문에, 사용자가 프로그램을 사용할 때 버벅이게 됨.

이미지 로딩을 뒤로 미루고, 필요할 때만 실제 이미지를 로딩하면 좋겠음.
여기서 가상 프록시가 등장함.


1-3. 구조

주요 클래스

  • Subject: 실제 객체와 프록시 객체가 공통으로 구현할 인터페이스
  • RealSubject: 실제 작업을 수행하는 객체 (ex. RealImage)
  • Proxy: 실제 객체에 대한 접근을 제어하는 프록시 객체 (ex. ImageProxy)
Client --> Proxy --> RealSubject
               |
           (접근 제어, 지연 로딩 등 수행)

1-4. 예제 코드 - Virtual Proxy

인터페이스 정의

public interface Icon {
    int getIconWidth();
    int getIconHeight();
    void paintIcon(Component c, Graphics g, int x, int y);
}

실제 이미지 클래스 (RealSubject)

public class ImageIcon implements Icon {
    private String filename;

    public ImageIcon(String filename) {
        this.filename = filename;
        loadImageFromDisk();
    }

    private void loadImageFromDisk() {
        System.out.println("디스크에서 이미지 로딩 중: " + filename);
    }

    public int getIconWidth() {
        return 800;
    }

    public int getIconHeight() {
        return 600;
    }

    public void paintIcon(Component c, Graphics g, int x, int y) {
        System.out.println("화면에 이미지 그리기: " + filename);
    }
}

프록시 클래스 (Proxy)

public class ImageProxy implements Icon {
    private String filename;
    private ImageIcon imageIcon;

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

    public int getIconWidth() {
        return (imageIcon != null) ? imageIcon.getIconWidth() : 600;
    }

    public int getIconHeight() {
        return (imageIcon != null) ? imageIcon.getIconHeight() : 400;
    }

    public void paintIcon(Component c, Graphics g, int x, int y) {
        if (imageIcon == null) {
            imageIcon = new ImageIcon(filename); // 실제 객체는 이 시점에 생성됨
        }
        imageIcon.paintIcon(c, g, x, y);
    }
}

클라이언트 사용 예

public class ImageViewer {
    public static void main(String[] args) {
        Icon icon = new ImageProxy("sample-image.jpg");

        // 아직 실제 이미지 로딩 안 됨
        System.out.println("아이콘 폭: " + icon.getIconWidth());

        // 이 시점에 이미지 로딩이 발생
        icon.paintIcon(null, null, 0, 0);
    }
}

1-5. 디자인 원칙 적용

  • OCP (Open-Closed Principle)
    실제 객체(RealImage)는 그대로 두고, 프록시(ImageProxy)를 추가함으로써 기능 확장
  • SRP (Single Responsibility Principle)
    ImageProxy는 지연 로딩에 대한 책임만 가지고, 이미지는 이미지 자체 처리만 담당

1-6. 사용 예시

  • 원격 객체 대리 (RMI, EJB 등)
  • DB Connection Pool
  • 가상 로딩 (이미지, 문서 등)
  • 접근 권한 제어

1-7. 정리

  • 프록시 패턴은 객체 접근을 제어함으로써 다양한 기능을 프록시 객체에 위임할 수 있음
  • 객체를 직접 건드리지 않고도 로직을 감쌀 수 있음
  • 데코레이터 패턴과 구조는 유사하나, 목적은 다름
    • 데코레이터: 기능 확장
    • 프록시: 접근 제어

profile
사부작ㅤ사부작

0개의 댓글