프록시 패턴이란?
프록시 패턴 이란
한줄 요약 : 프록시 패턴은 어떠한 객체를 대신하여 접근을 제어하는 등의 기능을 추가하는 디자인 패턴이다.
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
Comments powered by Disqus.