用处:为某个对象提供代理以控制对对象的访问。在某些情况下我们无法直接使用或访问对象,所以需要使用一层代理,通过代理访问对象。典型如网络中的代理服务器,网页加载时文字先加载,一些图片,视频后加载,在初期只提供这些这些资源开销大的对象的一个代理。
代理模式有好几种类型:
1. 远程代理(remote proxy):为一个位于不同地址空间的对象提供本地代理,隐藏一个对象存在于不同地址空间的事实。
2. 虚拟代理(virtual proxy): 根据需要创建开销很大的对象。
3. 保护代理(protection proxy): 控制对原始对象的访问,用于对象有不同访问权限的时候。
4. 智能指引(smart reference):取代简单指针,在访问对象时执行一些附加操作。
组成:
Proxy:
1.保存一个引用,使得代理可以访问实体。
2.提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。
3.控制对实体的存取,可能还负责实体的创建和删除。
Subject:
定义realSubject和proxy的共用接口,这样再任何使用realSubject的地方,都可以使用proxy。
realSubject:
定义proxy所代理的实体。
类图:
代码:
#include <cstdio> #include <stack> #include <set> #include <iostream> #include <string> #include <vector> #include <queue> #include <list> #include <functional> #include <cstring> #include <algorithm> #include <cctype> #include <string> #include <map> #include <iomanip> #include <cmath> #include <time.h> #define LL long long using namespace std; const int N=1000; // Subject class graphic { public: virtual void draw()=0; virtual void width()=0; virtual void heigh()=0; }; // realSubject class image:public graphic { public: // 加载image image(string name) { cout<<"construct image named "<<name<<endl; // ..... } void draw() { // draw image puts("realSubject: draw"); } void width() { puts("realSubject: width"); } void heigh() { puts("realSubject: heigh"); } }; //proxy image* loadAnImageFile(string name) { cout<<"load a image named "<<name<<endl; image* img = new image(name); // ..... return img; } class imageProxy:public graphic { private: image* img; string name; protected: image* loadImage() { if (!img) { img = loadAnImageFile(name); } return img; } public: imageProxy(string str):name(str) { img = NULL; } void draw() { loadImage()->draw(); } void heigh() { cout<<"proxy :"; loadImage()->heigh(); } void width() { cout<<"proxy :"; loadImage()->width(); } }; int main() { imageProxy *proxy = new imageProxy("image"); // .... 在需要用到image时候才创建 proxy->draw(); proxy->heigh(); proxy->width(); }
