CS/디자인패턴

[디자인 패턴][구조 패턴] - 프록시 패턴

흰무 2023. 8. 18. 09:55

1. 프록시 패턴

다른 객체에 대한 대리자 또는 대변자 역할을 수행하는 패턴
다양한 형태가 있지만, 가상 프록시, 보호 프록시가 대표적이다.
  • 사용하는 경우
    • 원본 객체에 대한 접근을 제어해야 할 때
    • 원본 객체의 생성 및 소멸에 대한 추가적인 기능을 제공해야 할 때
    • 원본 객체의 메서드 호출 전후에 추가적인 로직을 수행해야 할 때
    • 원본 객체의 접근을 제어하거나 보안을 강화해야 할 때
  • 구현 방법

프록시 패턴 UML 다이어그램

  1. 실제 주체 (Real Subject):
    • 프록시가 대리하는 실제 객체
    • 실제 작업을 수행하거나 수행할 수 있는 실제 비즈니스 로직이 구현
    • 프록시가 생성되거나 사용되는 시점에 실제 객체가 생성되고 초기화될 수 있음
  2. 프록시 (Proxy):
    • 실제 주체에 대한 대리자 역할
    • 실제 객체의 생성과 초기화를 지연시키거나, 접근 제어와 보호를 추가 가능
    • 프록시는 실제 주체와 동일한 인터페이스를 구현하며, 클라이언트는 프록시를 실제 주체와 동일하게 다룰 수 있음
  3. 클라이언트 (Client):
    • 프록시를 통해 실제 작업을 수행하는 주체
    • 실제 주체 대신에 프록시를 사용하여 작업을 요청하고 결과를 받음
    • 클라이언트는 프록시와 실제 주체의 차이를 모르고 사용할 수 있음
  • 예시
// 가상 프록시 (실제 객체의 생성을 늦추고, 필요한 시점에 생성)

interface Image {
    void display();
}

class RealImage implements Image {
    private String filename;

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

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

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

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();
    }
}

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

        // 이미지를 처음 표시할 때 실제 이미지가 로딩됨
        image1.display();

        // 이미지를 다시 표시할 때는 이미 로딩된 이미지를 사용
        image1.display();
        image2.display();
    }
}

 

// 보호 프록시 (실체 객체에 대한 접근을 제어, 보호)

interface File {
    void read();
}

class RealFile implements File {
    private String filename;

    public RealFile(String filename) {
        this.filename = filename;
        System.out.println("Creating file: " + filename);
    }

    public void read() {
        System.out.println("Reading file: " + filename);
    }
}

class ProxyFile implements File {
    private RealFile realFile;
    private String filename;
    private boolean accessAllowed;

    public ProxyFile(String filename, boolean accessAllowed) {
        this.filename = filename;
        this.accessAllowed = accessAllowed;
    }

    public void read() {
        if (accessAllowed) {
            if (realFile == null) {
                realFile = new RealFile(filename);
            }
            realFile.read();
        } else {
            System.out.println("Access denied to file: " + filename);
        }
    }
}

public class ProxyPatternExample {
    public static void main(String[] args) {
        File publicFile = new ProxyFile("public.txt", true);
        File privateFile = new ProxyFile("private.txt", false);

        publicFile.read();
        privateFile.read();
    }
}