【设计模式学习笔记十三】【结构型模式】【代理模式(Proxy)】
来源:互联网 发布:图书销售数据分析 编辑:程序博客网 时间:2024/06/16 11:01
本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:http://blog.csdn.net/lovelion/article/details/17517213
主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
1.代理模式
在软件开发中,有一种模式类似于代购,即客户端由于某种原因不想或不能直接访问一个对象,此时可以通过一个代理对象来实现间接访问,该方案被称为代理模式。
(1)定义
代理模式:为其他对象提供一种代理以控制对这个对象的访问。
代理又可分为四种:
a)远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是同一台主机中,也可以在另一台主机中,远程代理又称为大使。
b)虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正的创建。
c)保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
d)缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
e)智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来,比如智能指针。
1)代理模式结构图
2)参与者
a) Subject(抽象主题角色):定义RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用proxy。
b) RealSubject(真实主题角色):定义了Proxy所代表的实体。
c) Proxy(代理):保存一个引用是的代理可以访问实体;提供一个与Subject相同的接口,这样代理就可以用来替代实体;控制对实体的存取,并可能负责创建或删除它;其他功能依赖于代理的类型。
3)看图写代码
/*** FileName : ProxyPattern** Author : lin005** Date : 2015/01/29** Description : More information, please go to http://blog.csdn.net/amd123456789*/#include<iostream>#include<windows.h>using namespace std;//抽象主题角色class Subject{public:virtual void Request() = 0;};//真实主题角色class RealSubject:public Subject{public:void Request(){cout<<"RealSubject Request()"<<endl;}};//代理class Proxy:public Subject{public:Proxy(){real = new RealSubject();}~Proxy(){if(real != NULL){delete real;real = NULL;}}void preRequest(){cout<<"preRequest()"<<endl;}void postRequest(){cout<<"postRequest"<<endl;}//调用真正实体void Request(){preRequest();real->Request();postRequest();}private:RealSubject *real;};//客户端测试类int main(){Subject *proxy = new Proxy();proxy->Request();if(proxy){delete proxy;proxy = NULL;}return 0;}
4)智能指针
智能指针,使用引用计数时,也可以看做是代理模式的应用。下面例子中,SmartPtr就是代理类,实际对象是ptr;SmartPtr代理ptr的行为,运用引用计数,实现智能指针。
代码来自百度百科:
/*** FileName : ProxyPattern** Author : lin005** Date : 2015/01/30** Description : More information, please go to http://blog.csdn.net/amd123456789*///被代理的对象class Stub{public:void print(){cout<<"test"<<endl;}~Stub(){cout<<"stub::destructor"<<endl;}};//可以看做代理template<typename T>class SmartPtr{public:SmartPtr(T* p = 0):ptr(p),count(new size_t(1)){}SmartPtr(const SmartPtr<T> & src):ptr(src.ptr),count(src.count){++*count;}//重载赋值操作符SmartPtr& operator=(const SmartPtr & src){++*src.count;release();ptr = src.ptr;count = src.count;return *this;}T* operator->(){if(ptr)return ptr;}const T* operator->()const{if(ptr)return ptr;}T& operator*(){if(ptr)return *ptr;}const T& operator*()const{if(ptr)return *ptr;}~SmartPtr(){release();}private:void release(){if(--*count == 0){delete ptr;delete count;}}private:T* ptr;//真实对象size_t* count;//引用计数};int main(){//智能指针,类型为StubSmartPtr<Stub> t;t->print();//print testSmartPtr<Stub> t1(new Stub());SmartPtr<Stub> t2(t1);SmartPtr<Stub> t3(new Stub());t3= t2;//call t3 destructort1->print(); //print(*t3).print(); //printreturn 0;/*输出结果:teststub::destructor (析构t3)testteststub::destructor (析构t1)请按任意键继续. . .*/}
(2)总结
1)优点
a) 能够协调调用者和被调用者,在一定程度上降低了系统的耦合。
b) 客户端可以针对抽象角色进行编程。
2)缺点
a) 增加代理对象有些类型的代理模式可能会造成请求的处理速度变慢,例如保护代理。
b) 是在代理模式需要额外的工作,并且有些代理模式实现过程较为复杂,例如远程代理。
(3)适用场景
1)远程代理为一个对象在不同的地址空间提供局部代表;
2)虚代理根据需要创建开销很大的对象。
3)当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时使用保护代理
4)当需要为一个对象的访问提供额外的操作时,可以使用智能引用代理。
- 【设计模式学习笔记十三】【结构型模式】【代理模式(Proxy)】
- 设计模式学习笔记十三(Proxy代理模式)
- 设计模式深入学习--Proxy 代理模式(结构型模式)
- 设计模式学习笔记(十三)——Proxy代理
- C#面向对象设计模式纵横谈 学习笔记13 Proxy代理模式(结构型模式)
- 设计模式学习笔记--代理(Proxy)模式
- 结构型设计模式---代理模式(Proxy)
- 设计模式学习笔记(十三)——Proxy代理模式
- 设计模式学习笔记(十三)——Proxy代理模式
- [设计模式笔记]二. 结构型模式--13.Proxy模式(代理模式)(一)
- 设计模式-结构型模式:代理模式 Proxy
- 《设计模式》学习笔记--代理Proxy
- [设计模式学习笔记]PROXY(代理)
- 设计模式学习笔记(五)之代理模式(Proxy)
- java 设计模式学习笔记六 proxy代理模式
- 【设计模式】学习笔记15:代理模式(Proxy Pattern)
- 设计模式--学习笔记--代理模式Proxy--基础篇
- 设计模式学习笔记---代理模式Proxy(Java版)
- perl解决批量除去引物并生成FAST格式文件
- .Bat文件格式
- 2015—01—28 Shell学习笔记 条件分支
- Jconsole远程监控tomcat 的JVM内存(linux、windows)
- 数据结构——赫夫曼树
- 【设计模式学习笔记十三】【结构型模式】【代理模式(Proxy)】
- apk 签名备忘
- 每一个程序员需要了解的10个Linux命令
- UVA 11468 Substring AC自动机+概率DP
- qt 5 各种字符操作
- 修改DotNetBar控件库中MetroForm的边框颜色
- @selector
- c++_primer_exercise_1442
- Andorid获取状态栏高度