Thinking Different







Proxy Pattern - 프록시 패턴


  • 대리자로써 일을 맡기면 그 일을 처리하고 완료되면 그 결과를 알려주는 패턴입니다.
  • 프록시 패턴의 잘 알려진 예로는 참조 횟수 스마트 포인터가 있다. (shared_ptr, weak_ptr 등)






샘플 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//------------------------------------------------------------------
// Subject 인터페이스
class Subject
{
public:
    virtual void request() = 0;
};
 
//------------------------------------------------------------------
// RealSubject 상속 클래스
class RealSubject : public Subject
{
public:
    void request() { cout << "Response by RealSubject" << endl; }
};
 
//------------------------------------------------------------------
// Proxy 상속 클래스
class Proxy : public Subject
{
public:
    Proxy() : mReal(NULL) {}
    ~Proxy() { if (mReal) delete mReal; }
 
public:
    void request() 
    {
        if (!mReal) 
            mReal = new RealSubject; 
        
        mReal->request(); 
    }
 
private:
    RealSubject* mReal;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Subject* pProxy = new Proxy();
    pProxy->request();
    delete pProxy;
 
    return 0;
}




예제를 통한 프록시 패턴(Proxy Pattern) 알아보기



예제) 이미지 로딩 캐시 예제



RealImage에서는 이미지 파일을 디스크에서 읽어오는 함수와 출력하는 함수가 있고, ProxyImage에서 client와 인터페이스하는 함수를 정의하고 처리한다. 최초 사용시에 한번 디스크에서 이미지를 로딩하여 캐싱하고, 그 다음부터는 캐싱 이미지로 처리한다.



예제 코드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#if _UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif
 
//------------------------------------------------------------------
// Subject 인터페이스
class Image
{
public:
    virtual void ShowImage() = 0;
};
 
//------------------------------------------------------------------
// RealSubject 상속 클래스
class RealImage : public Image
{
public:
    RealImage(const TCHAR* name) : mFile(name) {}
 
public:
    void LoadImage() { wcout << "disk from loading file : " << mFile.c_str() << endl; }
    void ShowImage() { wcout << "show image : " << mFile.c_str() << endl; }
 
private:
    tstring mFile;
};
 
//------------------------------------------------------------------
// Proxy 상속 클래스
class ProxyImage : public Image
{
public:
    ProxyImage(const TCHAR* name) : mFile(name), mImage(NULL) {}
    ~ProxyImage() { if (mImage) delete mImage; }
 
public:
    void ShowImage() 
    {
        if (!mImage)
        {
            mImage = new RealImage(mFile.c_str());
            mImage->LoadImage();
        }
 
        mImage->ShowImage();
    }
 
private:
    RealImage* mImage;
    tstring mFile;
};
 
//------------------------------------------------------------------
// Main
int _tmain(int argc, _TCHAR* argv[])
{
    Image* pImage = new ProxyImage(_T("Image.png"));
    pImage->ShowImage();    // 로딩 및 출력
    pImage->ShowImage();    // 캐싱 출력
    pImage->ShowImage();    // 캐싱 출력
    delete pImage;
 
    return 0;
}


예제 결과)