意图:为其他独享提供一种代理以控制这个对象的访问。
适用性:
(1)远程代理:为一个对象在不同的地址空间提供局部代表。
(2)虚代理:根据需要创建开销很大的对象。
(3)保护代理:控制对原始对象的访问。
(4)智能指引:取代简单的指针,在访问对象时,执行一些附加操作,比如引用计数。
结构如下:
实现Gof的虚代理的例子:
class Graphic
{
public:
virtual ~Graphic() {}
virtual void Draw()=0;
virtual void GetExtent()=0;
virtual void Load()=0;
virtual void Save(const string& strFileName)=0;
protected:
Graphic() {}
};
class Image:public Graphic
{
public:
Image(const string& strFileName):strImageFileName(strFileName)
{
Load();
}
virtual ~Image() {}
virtual void Draw()
{
cout<<"Image::Draw()"<<endl;
}
virtual void GetExtent()
{
cout<<"Image::GetExtent()"<<endl;
}
virtual void Load()
{
cout<<"Image::Load()"<<endl;
cout<<"Load from "<<strImageFileName<<endl;// 此时真正的载入数据
}
virtual void Save(const string& strFileName)
{
cout<<"Image::Save(const string& strFileName)"<<endl;
cout<<"Save to "<<strFileName<<endl;
}
private:
string strImageFileName;
};
class ImageProxy:public Graphic
{
public:
ImageProxy(const string& strFileName):image(NULL),strImageFileName(strFileName) {}
virtual ~ImageProxy() {}
virtual void Draw()
{
cout<<"ImageProxy::Draw()"<<endl;
GetImage()->Draw(); //在真正需要图像的时候,载入数据
}
virtual void GetExtent()
{
cout<<"ImageProxy::GetExtent()"<<endl;
GetImage()->GetExtent();
}
virtual void Load()
{
cout<<"ImageProxy::Load()"<<endl; //实际上什么都不做,至此完成保存图像的路径即可
}
virtual void Save(const string& strFileName)
{
cout<<"ImageProxy::Save(const string& strFileName)"<<endl;
GetImage()->Save(strFileName); //将数据写入指定的文件
}
protected:
Image* GetImage()
{
if(image==NULL)
image=new Image(strImageFileName);
return image;
}
private:
Image* image;
string strImageFileName;
};
class TextDocument
{
public:
void Insert(Graphic* pGraphic)
{
mig.insert(pair<int,Graphic*>(mig.size(),pGraphic));
}
void ShowAllContext()
{
map<int,Graphic*>::iterator iter;
for(iter=mig.begin();iter!=mig.end();++iter)
{
cout<<iter->first<<endl;
iter->second->Draw();
iter->second->GetExtent();
}
}
~TextDocument()
{
map<int,Graphic*>::iterator iter;
for(iter=mig.begin();iter!=mig.end();++iter)
{
delete iter->second;
}
mig.clear();
}
private:
map<int,Graphic*> mig;
};
int _tmain(int argc, _TCHAR* argv[])
{
TextDocument* pTD=new TextDocument();
pTD->Insert(new ImageProxy("imageFileName1"));
pTD->Insert(new ImageProxy("imageFileName2"));
pTD->ShowAllContext();
delete pTD;
return 0;
}