意图:为其他对象提供一种代理以控制对这个对象的访问。
动机:对一个对象进行访问控制的一个原因是为了只有在我们确实需要这个对象时才对他进行创建和初始化。
适用性:
1 远程代理:为一个对象在不同的地址空间提供局部代表。
2 虚代理:根据需要创建开销很大的对象。
3 保护代理:控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
以下是运行时刻一种可能的代理结构的对象图:
参与者:
Proxy:
1 保持一个引用使得代理可以访问实体。若RealSubject和Subject的接口相同,Proxy会引 用Subject
2 提供一个与Subject的接口相同的接口,这样代理就可以用替代实体。
3 控制对实体的存取,并可能负责创建和删除它。
Subject:
定义RealSubject和Proxy的共用接口,这样任何使用RealSubject的地方都可以使用Proxy
RealSubject:定义Proxy所代表的实体。
协作:代理根据其种类,在适当的时候向RealSubject转发请求。
效果:Proxy在访问对象时引入了一定程度的间接性。根据代理的类型,附加的间接性有多种用途:
1 Romote Proxy:可以隐藏一个对象存在于不同地址空间的事实。
2 Virtual Proxy:可以进行最优化,例如根据需要创建对象
Adapter:为它所适配的对象提供了一个不同的接口。代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,所以,它的接口实际上可能只是实体接口的一个子集。
动机:对一个对象进行访问控制的一个原因是为了只有在我们确实需要这个对象时才对他进行创建和初始化。
适用性:
1 远程代理:为一个对象在不同的地址空间提供局部代表。
2 虚代理:根据需要创建开销很大的对象。
3 保护代理:控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
4 智能指引:取代了简单的指针,在访问对象时执行一些附加操作。典型用途包括:
(1)对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它。
(2)当第一次引用一个持久对象时,将它装入内存
(3)在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。
以下是运行时刻一种可能的代理结构的对象图:
参与者:
Proxy:
1 保持一个引用使得代理可以访问实体。若RealSubject和Subject的接口相同,Proxy会引 用Subject
2 提供一个与Subject的接口相同的接口,这样代理就可以用替代实体。
3 控制对实体的存取,并可能负责创建和删除它。
Subject:
定义RealSubject和Proxy的共用接口,这样任何使用RealSubject的地方都可以使用Proxy
RealSubject:定义Proxy所代表的实体。
协作:代理根据其种类,在适当的时候向RealSubject转发请求。
效果:Proxy在访问对象时引入了一定程度的间接性。根据代理的类型,附加的间接性有多种用途:
1 Romote Proxy:可以隐藏一个对象存在于不同地址空间的事实。
2 Virtual Proxy:可以进行最优化,例如根据需要创建对象
3 Protection Proxies和Smart Reference都允许在访问一个对象时有一些附加的内务处理
实现:
1 重载c++的存取运算符(智能指针就是)
3 Proxy并不是总是需要知道实体的类型。若Proxy能够完全通过一个抽象接口处理实体,则不用为每一个realsubject生成一个proxy。Proxy可以同意处理所有的realsubject.
Adapter:为它所适配的对象提供了一个不同的接口。代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,所以,它的接口实际上可能只是实体接口的一个子集。
Decorator:实现部分与代理类似,但是目的不一样,Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。
代码:
//代理模式:为其他对象提供一种代理以控制对这个对象的访问
#include <iostream>
#include <string>
using namespace std;
struct Point
{
int x;
int y;
Point() : x(0), y(0)
{
}
Point(int xx, int yy) : x(xx), y(yy)
{}
};
//代理和实际对象的接口
class Graphic
{
public:
virtual ~Graphic() {}
virtual void Draw(const Point& at) = 0;
virtual void HandleMouse(string event) = 0;
virtual const Point& GetExtent() = 0;
virtual void Load() = 0;
virtual void Save() = 0;
protected:
//构造函数是保护的,不能创建对象
Graphic(){}
};
//真实对象
class Image : public Graphic
{
public:
//从一个文件下载图片
Image(string file)
{
_fileName = file;
Point p(3, 4);
_extent = p;
}
~Image(){}
void Draw(const Point& at)
{
cout << "在点 (" << at.x << ","
<< at.y << ")处画" << endl;
}
void HandleMouse(string event)
{
cout << "执行事件" << event << endl;
}
const Point& GetExtent()
{
cout << "图像的尺寸是:" << _extent.x
<< "," << _extent.y << endl;
return _extent;
}
void Load()
{
cout << "载入图像..." << _fileName << endl;
}
void Save()
{
cout << "保存图像" << _fileName << endl;
}
private:
Point _extent;
string _fileName;
};
//代理
class ImageProxy : public Graphic
{
public:
//从一个文件下载图片
ImageProxy(string file) : _fileName(file), _image(0)
{
}
~ImageProxy()
{
delete _image;
}
void Draw(const Point& at)
{
GetImage()->Draw(at);
}
void HandleMouse(string event)
{
GetImage()->HandleMouse(event);
}
const Point& GetExtent()
{
if (_extent.x == 0 && _extent.y == 0)
_extent = GetImage()->GetExtent();
return _extent;
}
void Load()
{
GetImage()->Load();
}
void Save()
{
GetImage()->Save();
}
protected:
Image* GetImage()
{
if (_image == 0)
_image = new Image(_fileName);
return _image;
}
private:
Image* _image;
Point _extent;
string _fileName;
};
int main()
{
Point p(5, 9);
ImageProxy imp("picture1");
imp.Draw(p);
imp.HandleMouse("event1");
imp.GetExtent();
imp.Load();
imp.Save();
system("pause");
return 0;
}