프록시 패턴(Proxy Pattern)이란?
실제 기능을 수행하는 객체 Real Object 대신 가상의 객체 Proxy Object를 사용하여 로직의 흐름을 제어하는 디자인 패턴입니다.
이미지를 보면 Proxy는 RealSubject를 참조하고 있습니다. 동시에 Proxy와 RealSubject는 동일한 인터페이스 Subject를 구현합니다.
클라이언트(Client)는 Subject의 인터페이스를 참조하게 되는데, 앞서 말했듯이 Proxy는 RealSubject를 참조하고 있기 때문에 실제 이 Subject는 Proxy를 통해 RealSubject와 데이터를 주고 받게 됩니다.
쉽게 프록시는 RealSubject의 대리인 역할을 하는데요. 왜 이런 역할이 필요한 것일까요?
프록시 패턴의 취지는 RealSubject가 본연의 필수적인 역할만 수행할 뿐 부가적인 기능을 추가하지 않는 것에 있습니다. (단일 책임의 원칙, Single Responsesibility Principle)
예를들어 RealSubject의 역할이 메인 기능 외에도 DoAction(), beforeAction(), afterAction(), printLog(), checkRegex() 등 너무 많아진다면 RealSubject의 역할이 모호해지게 됩니다. (이는 위 프록시 패턴의 취지인 단일 책임 원칙을 위배하게 됩니다.)
아래 예시 코드를 통해 프록시 패턴을 조금 더 이해해보겠습니다.
import java.util.*;
// Subject
interface Image {
public void displayImage();
}
// RealSubject
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();
}
}
// Application
class ProxyApplication {
public static void main(String[] args) {
Image image1 = new ProxyImage("HiRes_Image1");
Image image2 = new ProxyImage("HiRes_image2");
image1.displayImage();
image2.displayImage();
}
}
위에서 이론으로 설명한 Subject, RealSubject, Proxy를 실제 코드로 구현한 것입니다.
Loading HiRes_Image1
Displaying HiRes_Image1
Loading HiRes_Image2
Displaying HiRes_image2
main method에 의해 출력되는 결과입니다.
ProxyApplication의 main 메서드를 보면 RealSubject인 RealImage class를 건드리지 않고 RealImage class의 loadImageFromDisk() 메서드를 통한 "Loading " + filename을 출력할 수 있습니다.
만약 RealImage class의 loadImageFromDisk() 메서드가 메인 기능이라고 한다면, RealSubject인 RealImage class는 그대로 두고 Image interface를 통해 추가되는 기능들을 구현해서 사용할 수 있게 됩니다.
하여 프록시 패턴의 취지인 단일 책임 원칙 (Single Responsibility Priciple)을 지킬 수 있게 됩니다.
프록시 패턴의 단점
이러한 프록시 패턴의 단점은 객체를 생성할 때, 한 단계를 더 거치게 되므로 빈번한 객체 생성이 필요한 경우에 성능이 저하될 수 있습니다.
그리고 로직이 복잡해지기 때문에 가독성이 떨어질 수 있습니다.
프록시 패턴의 대표적인 3가지
대표적으로 보호용 프록시(Protect Proxy), 가상 프록시(Virtual Proxy), 원격지 프록시(Remote Proxy)가 있습니다.
- 원격 프록시 : 원격 객체에 대한 접근 제어가 가능합니다. 서로 다른 주소 공간에 있는 객체에 대해 마치 같은 주소 공간에 있는 것처럼 동작하게 만드는 패턴입니다.
- 가상 프록시 : 객체의 생성 비용이 많이 드는 객체에 대해 가상 프록시를 생성하여 실질적으로 객체가 필요할 때까지 객체 생성을 시켜 메모리를 절약할 수 있습니다.
- 보호 프록시 : 주체 클래스에 대한 접근을 제어할 때 보호 프록시 패턴을 사용합니다. 클라이언트가 주체 클래스를 호출하려 할 때, 그 사이에서 프록시가 허용 여부를 결정할 수 있습니다.
프록시와 함께 이해하기 좋은 AOP
참고 자료
https://better-dev.netlify.app/java/2020/09/01/thejava_13/
'Programming > Web' 카테고리의 다른 글
Apache Log4j2 치명적 취약점, 해결방안은? CVE-2021-44228 (0) | 2021.12.12 |
---|---|
프로그래밍 시간 표현 단위 Unix Time ( = Epoch Time ) 이란 (0) | 2021.10.24 |
Web Socket 웹 소켓 개념 정리 (HTTP, Ajax) (0) | 2021.08.26 |
(Web) HTTP 통신의 개념과 예제 (0) | 2021.08.26 |
런타임 Run Time, 컴파일 타임 Compile Time 차이점 (0) | 2021.08.24 |