프록시 패턴이란?
- 어떤 객체에 대한 접근을 제어하는 대리 객체(Proxy Object) 를 제공하는 패턴
- 프록시는 실제 객체의 역할을 대신 수행하며, 성능 향상, 접근 제한, 지연 초기화, 로깅 등의 목적을 가짐
구성 요소
1. Subject (인터페이스 또는 추상 클래스)
Real Subject와 Proxy가 공통으로 구현해야 하는 인터페이스(추상 클래스)입니다.
2. Real Subject (실제 객체, 핵심 기능 담당)
실제로 작업을 수행하는 클래스
Proxy 객체는 Real Subject의 객체를 감싸서 대신 요청을 전달.
3. Proxy (대리 객체, 프록시 역할 수행)
Real Subject를 감싸고 있으며, 요청을 가로채거나 부가 기능 추가 가능
필요할 때만 Real Subject 객체를 생성하여 리소스 절약
접근 제어, 로깅, 캐싱, 성능 최적화 등의 역할 수행
패턴 흐름
1. 클라이언트는 Proxy 객체를 사용하여 요청을 보냄
2. Proxy 객체는 요청을 가로채고, 필요하면 Real Subject 객체 생성
3. Proxy 객체는 요청을 Real Subject에게 전달하고, 결과를 클라이언트에게 반환
4. 이 과정에서 프록시는 접근 제어, 로깅, 캐싱, 지연 초기화 등을 수행할 수 있음
프록시 패턴 예제 (C++)
1. #include <iostream>
2. #include <string>
3.
4. using namespace std;
5. typedef string MESH;
6.
7. MESH strSkinName[] =
8. {
9. "AHRI_CLASSIC",
10. "AHRI_FOXFIRE",
11. "AHRI_POPSTAR",
12. "AHRI_ACADEMY",
13. "AHAI_ARCADE",
14. };
15.
16. // 스킨을 적용하는 인터페이스 역할의 클래스
17. class Skin
18. {
19. public:
20. enum eSkinIndex
21. {
22. AHRI_CLASSIC = 0,
23. AHRI_FOXFIRE,
24. AHRI_POPSTAR,
25. AHRI_ACADEMY,
26. AHAI_ARCADE,
27. };
28.
29. // 챔피언에게 스킨을 적용하는 순수 가상 함수 (인터페이스 역할)
30. virtual void ApplyToChampion(const string strChampName) = 0;
31. };
32.
33. // 실제 스킨을 로드하고 적용하는 클래스 (RealSubject 역할)
34. class RealSkin : public Skin
35. {
36. private:
37. MESH m_strSkinName;
38.
39. public:
40. RealSkin(Skin::eSkinIndex eIndex)
41. {
42. // 실제 스킨 생성 시 무거운 처리
43. m_strSkinName = strSkinName[static_cast<int>(eIndex)];
44. LoadModel(m_strSkinName);
45. }
46.
47. void ApplyToChampion(const string strChampName)
48. {
49. cout << "The Skin Applied to " << strChampName << " is " << m_strSkinName << endl;
50.
51. }
52.
53. void LoadModel(const MESH modelName) const
54. {
55. cout << "Load Skin Model : " << modelName << endl;
56. }
57. };
58.
59.
60. class ProxySkin : public Skin
61. {
62. private:
63. RealSkin* m_pRealSkin; // RealSkin 클래스의 실제 객체를 가리키는 포인터
64. Skin::eSkinIndex m_eModelIndex;
65.
66. public:
67. ProxySkin(Skin::eSkinIndex eIndex)
68. {
69. m_pRealSkin = nullptr; // 실제 객체는 초기화하지 않음 (지연 생성)
70. m_eModelIndex = eIndex; // 스킨 인덱스만 저장해둠
71. }
72.
73. virtual ~ProxySkin()
74. {
75. delete m_pRealSkin;
76. }
77.
78. // 스킨을 챔피언에게 적용 (필요할 때 RealSkin을 생성)
79. void ApplyToChampion(const string strChampName) override
80. {
81. if (m_pRealSkin == nullptr)
82. m_pRealSkin = new RealSkin(m_eModelIndex);
83.
84. // 실제 객체의 ApplyToChampion 메서드 호출
85. m_pRealSkin->ApplyToChampion(strChampName);
86. }
87. };
88.
89. int main() {
90. // 프록시 객체 생성
91. ProxySkin* pProxy = new ProxySkin(Skin::AHAI_ARCADE);
92. pProxy->ApplyToChampion("Ahri");
93.
94. delete pProxy;
95. return 0;
96. }
97.
프록시 패턴 장점
1. 접근 제어 가능
2. 객체가 필요할 때만 리소스가 생성되므로 불필요한 리소스 낭비를 방지 (지연 초기화)
3. Proxy 객체에서 로그 기록, 캐싱, 성능 모니터링 등의 기능 쉽게 추가 가능 (로깅, 캐싱)
4. 클라이언트가 직접 Real Subject를 사용하지 않으므로, 직접 접근으로 인한 문제를 방지
프록시 패턴 단점
1. Proxy가 요청을 중간에서 처리하기 때문에, 성능 저하 발생 가능
2. Real Subject 외에 Proxy 객체까지 구현해야 하므로 코드가 복잡해질 수 있음
3. Proxy와 Real Subject가 같은 인터페이스를 구현해야 하므로, 일부 제한이 발생할 수 있음
'Unity > 디자인 패턴' 카테고리의 다른 글
| 디자인 패턴 (행위 패턴) - 인터프리터 패턴 (Interpreter Pattern) (0) | 2025.08.30 |
|---|---|
| 디자인 패턴 (행위 패턴) - 커맨드 패턴 (Command Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (구조 패턴) - 플라이웨이트 패턴 (Flyweight Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (구조 패턴) - 퍼사드 패턴 (Facade Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (구조 패턴) - 데코레이터 패턴 (Decorator Pattern) (0) | 2025.08.30 |