设计模式之代理模式(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;
}