🎈 프록시 패턴 (Proxy Pattern)
• 대상 원본 객체를 대신 처리하여 로직 흐름을 제어하는 패턴
• 프록시(Proxy) 사전적인 의미는 '대리인'
(= 누군가에게 어떤 일을 대신 시키는 것을 의미)
• 활용방안: 보안, 캐싱, 데이터 유효성 검사, 지연 초기화, 로깅 등
• 디자인 패턴 중 구조 패턴에 해당된다.
프록시 패턴 필요성
Q) 객체에 직접적으로 접근하면 되지 번거롭게 대리자를 통하는 이유는 무엇일까?
- 대상 클래스가 민감한 정보를 가지고 있는 경우
- 대상 객체가 무거운 경우
- 대상 객체에 기능 추가/변경이 쉽지 않은 경우
C++에서도 메모리 누수를 방지하고 자동으로 메모리를 해제하기 위해
스마트 포인터인 std::shared_ptr 또는 std::unique_ptr가 있는데
이는 대표적인 프록시 패턴 예시이다
[예제 코드]
• 프록시 패턴 적용 X
#include <iostream>
#include <string>
class Image {
public:
Image(const std::string& filename) : filename(filename) {
LoadImage();
}
void Display() {
std::cout << "[출력]: " << filename << std::endl;
}
private:
std::string filename;
void LoadImage() {
std::cout << "[로딩]: " << filename << std::endl;
}
};
int main() {
Image image("example.jpg");
puts("---- ---- ----");
image.Display();
return 0;
}
클라이언트(main)에서 image 객체를 생성하고 출력하고 있다.
Display() 메서드를 호출하기 전부터 이미지 생성/로딩을 하는데,
이는 리소스 낭비하고 있다고 볼 수 있다.
[예제 코드]
• 프록시 패턴 적용 O
#include <iostream>
#include <string>
class Image {
public:
virtual void Display() = 0;
};
class RealImage : public Image {
public:
RealImage(const std::string& filename) : filename(filename) {
LoadImage();
}
void Display() override {
std::cout << "[출력]: " << filename << std::endl;
}
private:
std::string filename;
void LoadImage() {
std::cout << "[로딩]: " << filename << std::endl;
}
};
class ImageProxy : public Image {
public:
ImageProxy(const std::string& filename) : filename(filename), realImage(nullptr) {}
void Display() override {
if (realImage == nullptr) {
realImage = new RealImage(filename);
}
realImage->Display();
}
private:
std::string filename;
RealImage* realImage;
};
int main() {
Image* image = new ImageProxy("example.jpg");
puts("---- ---- ----");
image->Display();
return 0;
}
Display() 메서드 호출할 때, 이미지가 로딩된다.
실제 객체 생성하거나 초기화하지 않고
클라이언트 요청에 응답하여 리소스를 효율적으로 관리할 수 있다. (성능 향상)
이러한 방법을 "지연 초기화/로딩 (Lazy Initialization/Loading)"라고 하는데
데이터베이스 엔티티나 이미지 등에서 활용된다.
프록시 패턴 유의사항
• 복잡성 증가: 프록시 패턴 도입으로 추가적인 클래스와 인터페이스 필요
• 성능 저하: 중간에서 처리하기에 직접 접근하는 것보다 성능저하가 발생할 수 있다.
🎈 다른 디자인 패턴과 비교
두 개의 객체를 이어준다는 역할적인 측면에서 두 패턴은 서로 유사하다.
어댑터 패턴은 서로 다른 인터페이스를 호환해주는 것이 목적이고
프록시 패턴은 객체에 대한 직접 접근을 제어하고 추가 동작을 수행하는 것에서 차이가 있다.
'까망 동네 > 디자인 패턴' 카테고리의 다른 글
[디자인패턴] 방문자 패턴 (Visitor Pattern) (3) | 2023.11.13 |
---|---|
[디자인 패턴] 경량 패턴 (Flyweight Pattern) (2) | 2023.11.12 |
[디자인 패턴] 메멘토 패턴 (Memento Pattern) (1) | 2023.11.10 |
[디자인패턴] 퍼사드 패턴 (Facade Pattern) (54) | 2023.11.09 |
[디자인 패턴] 관찰자(Observer) 패턴 (4) | 2023.11.06 |
댓글