- 프록시 패턴(proxy pattern)은 컴퓨터 프로그래밍에서 소프트웨어 디자인 패턴의 하나이다.
- 일반적으로 프록시는 다른 무언가와 이어지는 인터페이스의 역할을 하는 클래스이다. 프록시는 어떠한 것(이를테면 네트워크 연결, 메모리 안의 커다란 객체, 파일, 또 복제할 수 없거나 수요가 많은 리소스)과도 인터페이스의 역할을 수행할 수 있다.
- 쉽게 말해서 페이스북을 하다가 특정 글의 댓글을 보고 싶어서 눌렀는데 2천개나 댓글이 갑자기 로드가 되어버리면 메모리 낭비가 발생되지 않을까? 사용자 측면에서도, 호스트 입장에서도 불편할 것이다.
그렇기 때문에 한 번에 많은 양이 아닌 10개, 20개 씩 사용자에게 일부분의 데이터만 제공하기 위해 사용되는 패턴이라고 생각하면 된다.
- 이 프록시 패턴은 Eager Lazy, 지연 로딩이라고 하는, 데이터베이스에서 불필요한 데이터를 조회에서 성능을 낭비하게 되는 것을 방지하기 위해서 나온 패턴이라는 것을 참고로 알아두길 바란다.
- Proxy는 대리인이라는 뜻으로, 어떤 클래스의 업무 처리가 늦어질 경우 Proxy가 업무를 분담하여 처리해준다고 생각하면 된다. 예를 들어, A 아르바이트 생에게 상자 500개를 창고에 넣으라는 지시와 포장 100개를 해놓으라는 지시를 했는데 지시가 완료된 시간은 3시간이었다.
이번에는 '할일이 없는' 아르바이트 생들에게 상자 500개를 창고에 넣으라는 지시와 포장 100개를 해놓으라는 지시를 했는데 총 2명이 업무를 진행했고, 지시가 완료된 시간은 1시간이었다.
실질적으로 A 아르바이트생이 500개를 운반했고, 할일이 없던 B 아르바이트생이 포장 100개를 같이 진행한 것이다.
이처럼 특정 대상이 해야할 일을 대리인을 통해서 분담을 했다, 라고 생각하면 편하다.
- 위의 예로 흐름도를 분석해본다면 interface에 해당하는 것이 아르바이트이다.
이 interface에서는 업무를 진행하고 있는 여부 isDoWork()와, 업무를 진행하라는 DoWork() 메서드가 있다고 가정한다.
일반적으로 생각해보면 interface 같은 것을 만들지 않고 Class 아르바이트생 -> DoWork() 호출을 할텐데 이 작업이 3시간이 걸렸다는 것이다.
이때 Proxy를 거쳐서 일을 하고 있는 아르바이트생이 있다면(isDoWork()) 새로운 아르바이트 생에게 다른 일을 맡긴다는 과정을 추가함으로 시간을 감소시킨 것이다.
- 아래 코드는 Image를 예시로 든 Proxy 패턴 코드이다.
import java.util.*;
interface Image {
public void displayImage();
}
// 실제로 이미지를 출력하는 클래스
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadImageFromDisk();
}
private void loadImageFromDisk() {
System.out.println("Loading " + filename);
}
@Override
public void displayImage() {
System.out.println("Displaying " + filename);
}
}
// 실제로 일을 하고 있는 이미지를 확인하는 Proxy 클래스
class ProxyImage implements Image {
private String filename;
private Image image;
public ProxyImage(String filename) {
this.filename = filename;
}
@Override
public void displayImage() {
if (image == null)
image = new RealImage(filename);
image.displayImage();
}
}
class ProxyExample {
public static void main(String[] args) {
Image image1 = new ProxyImage("Bird.jpg");
Image image2 = new ProxyImage("Lion.jpg");
image1.displayImage();
image2.displayImage();
}
}