포스트

프록시 패턴이란?

프록시 패턴 이란

한줄 요약 : 프록시 패턴은 어떠한 객체를 대신하여 접근을 제어하는 등의 기능을 추가하는 디자인 패턴이다.

Proxy는 직역하면 대리를 뜻한다. 즉, 무언가를 대신 처리해주는 것이다.
순차 다이어그램으로 그려보면 다음과 같다.

사진에서 보이듯 클라이언트는 실제 객체에 접근하지 않고, Proxy를 통해 접근하고 있다. 따라서 Proxy실제 객체Wrapping한 객체라고 볼 수 있다.

이렇게 Proxy로 접근하면 얻을 수 있는 이점이 뭐가 있을까?

프록시 패턴의 장점

필요한 시점에 객체 초기화를 할 수 있다.

프록시 패턴을 사용하면, 객체 초기화를 최대한 늦게 시켜 리소스 부담을 덜 수 있다.

아래와 같이 이미지를 출력하는 Image 인터페이스가 있다.

1
2
3
public interface Image {  
  void displayImage();   
}

그리고 인터페이스를 구현한 RealImage 객체가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class RealImage implements Image {  
  File file;
  String fileName;  
  
  public RealImage(String fileName) {  
    this.fileName = fileName;  
    // 이미지 로딩 작업
  }  
  
  @Override  
  public void displayImage() {  
    // 이미지 display 작업
  }  
}

만일 RealImage 객체가 초기화되는데 많은 리소스를 잡아 먹는다면, 애플리케이션이 다소 부담스러울 수 있다. 그래서 ProxyImage 라는 객체를 만들었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ProxyImage implements Image {  
  Image image;  
  String fileName;  
  
  public ProxyImage(String fileName) {  
    this.fileName = fileName;  
  }  
  
  @Override  
  public void displayImage() {  
    if (this.image == null) {  
      this.image = new RealImage(fileName);  
    }  
  
    this.image.displayImage();  
  }  
}

이제 ProxyImage를 사용하면 displayImage()를 호출할때 초기화 되기 때문에, 초기화를 원하는 시점에 할 수 있게 된다.

1
2
3
4
5
public static void main(String[] args) {  
  Image image1 = new ProxyImage("hello.png");  
  // ....... 기타 원하는 작업들 (중략)
  image1.displayImage();  
}

OOP스럽게 기능을 추가 할 수 있다.

만일 아까 코드에서 Image를 로딩할때, 로드되는 시간을 기록하는 기능을 만들고 싶다고 가정하자. 당장은 이렇게 짤 수 있다.

1
2
3
4
5
6
7
8
9
public RealImage(String fileName) {  
  long beforeTime = System.currentTimeMillis();  
  
  this.fileName = fileName;  
  // 이미지 로드 작업...  
  
  long afterTime = System.currentTimeMillis();  
  System.out.println("실행 소요시간 : " + (afterTime - beforeTime));  
}

하지만 이는 OOP스럽지 못하다. 결국 단일 책임 원칙(SRP) 을 위배했기 때문이다. 우리는 프록시 패턴을 배웠으니, 프록시 객체에서 따로 로깅을 하도록 해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ProxyImage implements Image {  
  Image image;  
  String fileName;  
  
  public ProxyImage(String fileName) {  
    this.fileName = fileName;  
  }  
  
  @Override  
  public void displayImage() {  
    if (this.image == null) {  
      long beforeTime = System.currentTimeMillis();  
      this.image = new RealImage(fileName);  
      long afterTime = System.currentTimeMillis();  
      System.out.println("실행 소요시간 : " + (afterTime - beforeTime));  
    }  
  
    this.image.displayImage();  
  }  
}

결국 원래 코드는 건들이지 않고 로깅 기능을 추가하게 되었다. - 개방 폐쇄 원칙(OCP)

프록시 패턴의 단점

코드가 복잡해진다

위 예시에서 봤듯, 프록시 객체 관련 코드들이 생겨나기 때문에 코드가 다소 복잡해질 수 있다.

Reference

  • 자바 ORM 표준 JPA 프로그래밍 (김영한 저)
  • https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9D%EC%8B%9C_%ED%8C%A8%ED%84%B4
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

Comments powered by Disqus.