Hello

[디자인 패턴] - Proxy

by 볼빵빵오춘기

Proxy

어떤 객체에 대한 접근을 제어하기 위해 그 객체를 대신해서 행동하는 객체이다.

즉, 원래 객체에 직접 접근하지 않고, 그 객체의 대리인을 통해 간접적으로 접근하게 해주는 디자인 패턴이다.

 

예시 코드

// Subject (인터페이스)
interface Image {
    void display();
}

// RealSubject (실제 객체)
class RealImage implements Image {
    private String filename;

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

    private void loadFromDisk() {
        System.out.println("이미지 로딩 중: " + filename);
    }

    public void display() {
        System.out.println("이미지 표시: " + filename);
    }
}

// Proxy
class ProxyImage implements Image {
    private RealImage realImage;
    private String filename;

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

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename); // 필요한 시점에만 생성
        }
        realImage.display();
    }
}

// Client
public class ProxyPatternExample {
    public static void main(String[] args) {
        Image image = new ProxyImage("photo.jpg");

        // 실제 이미지는 여기서 처음 로드됨 (지연 로딩)
        image.display();

        // 두 번째 호출은 캐시된 객체 사용
        image.display();
    }
}

 

Proxy 패턴의 장점

접근 제어

권한이 있는 사용자만 실제 객체에 접근하게 할 수 있다.

 

지연 로딩(Lazy Initialization)

실제 객체 생성을 나중으로 미뤄서 성능 최적화가 가능하다.

 

리소스 절약

무거운 객체를 바로 생성하지 않고, 필요할 때만 생성 가능하다.

 

로깅 / 감시 / 캐싱 가능

실제 객체 호출 전후로 추가 기능 삽입 가능하다. (예: 로깅, 보안)

 

Proxy 패턴의 단점

구조 복잡성 증가

Proxy 객체, 실제 객체, 인터페이스로 나눠야 하므로 구조가 복잡해질 수 있다.

 

성능 문제

잘못 구현하면 오히려 성능 저하(예: 캐시 미스, 중복 호출 등) 발생한다.

 

디버깅 어려움

중간에 Proxy가 끼어 있어 버그 추적이 어려울 수 있다.

 

Proxy 패턴 언제 사용하나?

접근 제한이 필요할 때

사용자가 특정 객체에 접근 가능한지 제어해야 할 때

 

무거운 객체의 생성을 늦추고 싶을 때

이미지 뷰어, DB 연결 등 리소스가 큰 객체의 경우

 

기능 확장이 필요할 때

로깅, 인증, 트랜잭션 처리 등 부가 기능을 객체 접근에 삽입하고 싶을 때

 

캐싱을 통해 성능 향상하고 싶을 때

같은 요청에 대해 캐시된 응답을 제공하려는 경우

 

정리하자면

Proxy 패턴은 실제 객체에 직접 접근하지 않고, 중간에 대리 객체를 두어 접근을 제어하거나 기능을 추가하는 패턴이다.

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기