728x90
프록시 패턴 (Proxy Pattern)
- 프록시(Proxy) : 대리자, 대변인 / 누군가를 대신해서 그 역할을 수행한다
- 즉, 프록시에게 어떤 일을 대신 시키는 것이다
- 어떤 객체를 사용하고자 할 때, 객체를 직접적으로 참조하는 것이 아닌 해당 객체를 대항하는 객체를 통해 대상 객체에 접근하는 방식이다
- 이를 사용하면 해당 객체가 메모리에 존재하지 않아도 기본적인 정보를 참조하거나 설정할 수 있고, 실제 객체의 기능이 필요한 시점까지 객체의 생성을 미룰 수 있다
- 스프링 AOP의 공통의 기능을 구현할 때 프록시 패턴을 이용하기도 한다
프록시 패턴의 장점
- 메모리 사용량이 큰 객체가 로딩되기 전에 프록시를 통해 참조가 가능하다
- 실제 객체의 public, protected 메소드를 숨기고 인터페이스를 통해 노출시킬 수 있다
- 로컬에 있지 않고 떨어져 있는 객체를 사용할 수 있다
- 원래 객체의 접근에 대해 사전 처리를 할 수 있다
프록시 패턴의 단점
- 객체를 생성할 때 한 단계를 거치게 되므로, 빈번한 객체 생성이 필요한 경우 성능이 저하될 수 있다
- 프록시 내부에서 객체 생성을 위해 스레드가 생성, 동기화가 구현되어야 하는 경우 성능이 저하될 수 있다
- 로직이 난해해져 가독성이 떨어질 수 있다
프록시 패턴의 특징
- 대리자는 실제 서비스와 같은 이름의 메소드를 구현한다
- 대리자는 실제 서비스에 대한 변수를 갖는다
- 대리자는 실제 서비스와 같은 이름의 메소드를 호출하고 그 결과를 클라이언트에 반환한다
- 대리자는 실제 서비스 메소드 호출 전후 별도의 로직 수행 가능
프록시 패턴을 사용하는 이유
- 프록시 객체가 클라이언트의 모든 요청을 받아서 실제 객체의 서비스에 대한 접근의 흐름을 제어하면서 서비스를 유연하게 제공할 수 있다
- 또한 실제 객체를 수행하기 이전에 전처리를 하거나, 기존 객체를 캐싱할 수 있다
- 기존 객체의 리소스가 무거울 경우, 이러한 캐싱 과정을 통해 부하를 줄일 수 있다는 장점이 있다
- 기존 객체를 수정하지 않고 일련의 로직을 프록시 패턴을 통해 추가할 수 있다
- 프록시는 기존 객체와 클라이언트의 요청 사이에 위치해 있기 때문에 하나의 방패(보안) 역할을 하기도 한다
프록시 패턴의 종류
가상 프록시 (Virtual Proxy)
- 생성하기 힘들거나 비용이 많이 드는 객체를 대신하는 역할을 맡는다
- 꼭 필요로 하는 시점까지 객체의 생성을 연기하고, 해당 객체가 생성된 것처럼 동작하도록 만들고 싶을 때 사용하는 패턴이다
- 즉, 실제 객체의 사용 시점을 제어하여 클라이언트가 처음 요청 및 접근할 때만 실제 객체가 생성되며 이후는 프록시를 참조하여 실제 객체를 대신할 수 있다
- 프록시 클래스에서 작은 단위의 작업을 처리하고 리소스가 많이 요구되는 작업들이 필요할 경우만 주체 클래스를 사용하도록 구현한다
원격 프록시 (Remote Proxy)
- 원격 프록시는 다른 JVM에 위치한 객체와 정보를 주고 받는다
- 원격 객체에 대한 접근을 제어 로컬 환경에 존재하며, 원격 객체에 대한 대변자 역할을 하는 객체
- 서로 다른 주소 공간에 있는 객체에 대해 마치 같은 주소 공간에 있는 것처럼 동작하는 패턴이다
- 원격 프록시의 메소드를 호출하게 되면 네트워크를 통해 전달되어 원격 객체의 메소드가 호출되며, 이러한 결과는 다시 클라이언트에게 전달된다
보호 프록시
- 객체에 대한 접근 권한을 부여하는 역할을 한다
- 민감한 객체에 대해 접근을 제어할 수 있다
- 주체 클래스에 대한 접근을 제어하기 위한 경우에 객체에 대한 접근 권한을 제어하거나 객체마다 접근 권한을 달리하고 싶을 경우 사용하는 패턴이다
- 프록시 클래스에서 클라이언트가 주체 클래스에 대한 접근을 허용할지 말지 결정하도록 할 수 있다
프록시 패턴 구현 - JAVA
예시로 용량이 큰 이미지와 글이 같이 있는 문서를 화면에 띄운다고 가정해보자
텍스트는 용량이 작아서 빠르게 나타나지만, 이미지는 용량이 크기 때문에 느리게 로딩되는 것을 확인할 수 있다
만약 이렇게 처리되지 않고 텍스트와 이미지 로딩이 모두 끝난 후 화면이 나온다면 사용자는 로딩이 끝날 때까지 기다려야 한다
따라서 로딩이 먼저 끝난 텍스트를 먼저 나오게 하는 것이 좋다
이와 같은 방식을 가지려면 텍스트 처리용 프로세스, 이미지 처리용 프로세스를 별도로 운영하면 된다!
Image.java
public interface Image {
public void displayImage();
}
Real_Image.java
public class Real_Image implements Image {
private String fileName;
public Real_Image(String fileName) {
this.fileName = fileName;
}
private void loadFromDisk(String fileName) {
System.out.println("로딩: " + fileName);
}
@Override
public void displayImage() {
System.out.println("보여주기: " + fileName);
}
}
Porxy_Image.java
public class Proxy_Image implements Image {
private String fileName;
private Real_Image realImage;
public Proxy_Image(String fileName) {
this.fileName = fileName;
}
@Override
public void displayImage() {
if (realImage == null) {
realImage = new Real_Image(fileName);
}
realImage.displayImage();
}
}
Proxy_Pattern.java
public class Proxy_Pattern {
public static void main(String args[]) {
Image image1 = new Proxy_Image("test1.jpg);
Image image2 = new Proxy_Image("test2.jpg);
image1.displayImage();
image2.displayImage();
}
}
위의 코드와 같이 Proxy_Pattern 클래스에서 Real_Image 클래스에 직접 접근하지 않고, Proxy_Image 클래스에서 객체를 생성하여 대신 일을 수행하는걸 확인할 수 있다
참고)
https://wellsw.tistory.com/218
https://today-retrospect.tistory.com/102
https://crazy-horse.tistory.com/117
728x90
'야미스터디 > Design pattern' 카테고리의 다른 글
[디자인 패턴] 퍼사드 패턴 📌 (0) | 2022.10.04 |
---|---|
[디자인 패턴] 상태 패턴 (State Pattern) 📌 (0) | 2022.08.24 |
[디자인 패턴] 싱글톤 패턴 📌 (0) | 2022.08.21 |
[디자인 패턴] 디자인 패턴이란? (0) | 2022.08.21 |
댓글