반응형
프록시 패턴이란?
객체의 대변인 역할을 하는 객체를 만들어 제공하는 패턴이다. 그렇기에 프록시객체를 통해 접근을 제어하고 요청을 전달하며 전/후 처리를 수행하는 역할을 하게 된다.
예를 들어 우리가 은행에 가서 직접 거래를 하지 않고 ATM이라는 프록시를 통해 거래를 처리하는 것과 같다.
왜 사용해야 하는가?
- 원래 객체에 대한 접근 제어가 가능하다.
- 요청의 전처리나 후처리를 수행하여 로깅, 트랜잭션 관리 등의 기능을 추가할 수 있다.
- 원래 객체의 생성 비용이 높을 경우 프록시를 통해서 필요한 경우에만 객체를 생성하도록 하여 생성 비용을 절감할 수 있다
어떤 경우에 사용하는가?
- 접근 제어 혹은 전/후처리가 필요한 경우
- 지연로딩이 필요한 경우(객체의 생성 비용이 높은 경우)
문제점
- 프록시 객체를 추가해야 하기 때문에 코드가 복잡해질 수 있다.
- 전/후 처리를 하기 때문에 응답이 늦어질 수 있다.
구현 방법
이미지를 로드하기 위해서는 시간이 걸리는 작업이라고 했을때 프록시를 이용해 이를 캐싱해 두어 두 번째 요청부터는 시간이 짧게 걸리도록 구현을 해보았다.
먼저 이미지 인터페이스를 만들어 주었다.
package com.example.designpattern.stuctural.proxy.image;
public interface Image {
void display();
}
다음으로는 실제로는 아니지만 시간이 걸리는 작업을 가정하고 디스크로부터 이미지를 읽어와서 표시해주는 객체를 생성하였다.
해당 객체는 생성할때 비교적 많은 비용이 발생하게 되어 프록시 없이 매번 객체를 읽어온다면 많은 비용 낭비가 발생할 것이다.
package com.example.designpattern.stuctural.proxy.image;
public class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
try {
loadFromDisk();
} catch (InterruptedException e) {
System.out.println("이미지 로드에 실패하였습니다.");
}
}
public String getFilename() {
return filename;
}
private void loadFromDisk() throws InterruptedException {
System.out.println("이미지 로드 시작...");
// 1 ~ 3 초사이
Thread.sleep(1000 + (long) (Math.random() * 2000));
System.out.println("이미지 로드 완료...");
}
@Override
public void display() {
System.out.println("이미지 디스플레이: " + filename);
}
}
이를 해결하기 위해서 프록시 객체를 두고 해당 객체를 캐싱하는 작업을 해보았다.
package com.example.designpattern.stuctural.proxy.image;
public class ProxyImage implements Image{
private RealImage realImage;
public ProxyImage(String filename) {
this.realImage = new RealImage(filename);
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(realImage.getFilename());
}
realImage.display();
}
}
캐싱의 효과도 있지만 실제로 이미지를 출력할 때 적자할 수 있도록 하는 지연 효과도 누릴 수 있게 되었다.
package com.example.designpattern.stuctural.proxy;
import com.example.designpattern.stuctural.proxy.image.Image;
import com.example.designpattern.stuctural.proxy.image.ProxyImage;
public class ProxyClient {
public static void main(String[] args) {
Image image = new ProxyImage("text.jpg");
for (int i = 0; i < 10; i++) {
image.display();
}
}
}
클라이언트는 어렵지 않게 해당 프록시를 사용할 수 있게 되었다.
이미지 로드 시작...
이미지 로드 완료...
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
이미지 디스플레이: text.jpg
결과화면을 보면 이미지 로드는 최초에 한 번만 실행하는 것을 볼 수 있다.
반응형
'Design Pattern > 구조 패턴(Structural patterns)' 카테고리의 다른 글
Flyweight Pattern, 플라이웨이트 패턴 (0) | 2024.02.14 |
---|---|
Facade Pattern, 퍼사드 패턴 (0) | 2024.02.07 |
Decorator Pattern, 데코레이터 패턴 (1) | 2024.02.06 |
Composite Pattern, 복합체 패턴 (0) | 2024.02.05 |
Bridge Pattern, 브릿지 패턴 (0) | 2024.02.05 |