設計模式之代理模式(ProxyPattern)

設計模式之代理模式(ProxyPattern)


一.代理模式(ProxyPattern)

代理模式是創建一個代理類,來幫助我們處理真實類,一般來說,這種代理類有點像明星的經紀人,如果你想接觸到明星,必須先和他們的經紀人打交道。

注: 接下來爲了方便理解類之間的設計關係,採用StartUML畫類圖,用C++編程

二.編程實例

1.圖片讀取案例

我們再讀取圖片文件時,並不會每一次都把它從磁盤中進行讀取,而是用一個代理類來判斷這個圖片是否已經加載過,如果加載過,那就不用從圖片中再次讀取,可以直接顯示。
類圖設計
在這裏插入圖片描述

程序

#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;


/*
設計模式之代理模式:


*/

/************************抽象類**************************/
class Image
{
public:
    virtual void display() = 0;
};

/************************真實類**************************/
class RealImage:public Image
{
public:
    string _filename;
public:
    RealImage(string filename)
    :_filename(filename)
    {
        loadFromDisk();
    }

    void loadFromDisk()
    {
        cout << _filename << "is loading from disk, it may cost some time" << endl;
    }

    void display()
    {
        cout << "display: " << _filename << endl;
    }
};


/************************代理類**************************/
class ProxyImage:public Image
{
public:
    RealImage* _realImage;
    string _filename;

public:
    ProxyImage(string filename)
    :_filename(filename)
    ,_realImage(NULL)
    {}

    void display()
    {
        if (_realImage == NULL)
            _realImage = new RealImage(_filename);
        _realImage->display();
    }
};


int main()
{
    Image *image1 = new ProxyImage("Adult Picture");
    image1->display();
    
    cout << "I want to see Adult Picture again" << endl;
    image1->display();


    return 0;
}

2.String類訪問修飾符[]讀寫操作區分案例

這個案例有一些難度,如果像瞭解完整的String類實現,可以參考我的另一篇文章:String類COW寫時複製技術
在我們重載訪問修飾符[]的時候,我們並不能夠分清楚它究竟是要進行讀操作還是寫操作,因爲寫操作需要重新分配內存而讀操作不需要,所以我們用一個代理類來幫助我們進行判斷。

程序

#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;


//沒有用代理模式
#if 0
class String
{
    char *_pstr;

public:
    String()
        : _pstr(new char[100])
    {
        _pstr[0] = 'a';
    }

    char &operator[](int idx)
    {
        cout << "無法分清讀寫操作,直接重新分配內存,很消耗時間" << endl;
        _pstr = new char[100];
        _pstr[0] = 'a';
        return _pstr[idx];
    }

    void operator=(const char &ch)
    {
        _pstr[0] = ch;
    }
};
#endif


//使用代理模式
#if 1
class String
{
    char *_pstr;

public:
    //代理類
    class CharProxy
    {
        String &_string;
        int _idx;

    public:
        CharProxy(String &string, int idx)
            : _string(string), _idx(idx)
        {
        }

        //讀操作
        operator char()
        {
            return _string._pstr[_idx];
        }

        //寫操作
        void operator=(const char &ch)
        {
            cout << "重新分配內存" << endl;
            _string._pstr[_idx] = ch;
        }
    };

public:
    String()
        : _pstr(new char[100])
    {
        _pstr[0] = 'a';
    }

    CharProxy operator[](int idx)
    {
        return CharProxy(*this, idx);
    }

    char *c_str()
    {
        return _pstr;
    }
};
#endif


int main()
{
    String s1;
    cout << s1[0] << endl;
    s1[0] = 'd';

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章