프록시 패턴은 객체에 대한 접근을 제어하는 대리인을 제공하는 구조적 디자인 패턴임.
즉, 어떤 객체가 있을 때 그 객체를 직접 사용하지 않고, 대신 프록시 객체를 통해 접근하게 함으로써,
접근 제어, 지연 로딩, 권한 제어, 원격 접근 등 부가적인 책임을 수행할 수 있게 함.
어떤 이미지 뷰어 프로그램이 있고, 사용자가 그림을 클릭하면 큰 이미지가 뜨게 되어 있음.
하지만 이미지를 불러오는 데 시간이 오래 걸리기 때문에, 사용자가 프로그램을 사용할 때 버벅이게 됨.
이미지 로딩을 뒤로 미루고, 필요할 때만 실제 이미지를 로딩하면 좋겠음.
여기서 가상 프록시가 등장함.
주요 클래스
Subject: 실제 객체와 프록시 객체가 공통으로 구현할 인터페이스 RealSubject: 실제 작업을 수행하는 객체 (ex. RealImage) Proxy: 실제 객체에 대한 접근을 제어하는 프록시 객체 (ex. ImageProxy)Client --> Proxy --> RealSubject
|
(접근 제어, 지연 로딩 등 수행)
public interface Icon {
int getIconWidth();
int getIconHeight();
void paintIcon(Component c, Graphics g, int x, int y);
}
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);
}
}
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);
}
}
RealImage)는 그대로 두고, 프록시(ImageProxy)를 추가함으로써 기능 확장 ImageProxy는 지연 로딩에 대한 책임만 가지고, 이미지는 이미지 자체 처리만 담당