博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式】为别人做嫁衣 --- 代理模式
阅读量:5815 次
发布时间:2019-06-18

本文共 4172 字,大约阅读时间需要 13 分钟。

一,概述

        定义:代理模式(Proxy)为另一个对象提供一个替身或占位符以控制对这个对象的访问,简而言之就是用一个对象来代表另一个对象。

         
作用:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端
和目标对象之间起到中介的作用。

        思想:为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。

 

        远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是局域的而不是远程的,而代理对象承担了大部份的网络通讯工作。由于客户可能没有意识到会启动一个耗费时间的远程调用,因此客户没有必要的思想准备。

        虚拟(Virtual)代理(图片延迟加载的例子):根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。使用虚拟代理模式的好处就是代理对象可以在必要的时候才将被代理的对象加载;代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的情况下,虚拟代理的好处就非常明显。

       Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。

        智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

 

 

二,示例

         描述:卓贾易让戴励送给李娇娇礼物,追求李娇娇。

 

        1)小菜第一版代码

               缺点:卓贾易直接行使送礼物类,不符合题目意思。

 

#include 
class SchoolGirl //要追的女孩 {public: void SetName(std::string str)//名字 { m_Name = str; }; std::string GetName(void) //获取女孩名字 { return m_Name; };private: std::string m_Name;};class Pursuit//追求行为类 {public: Pursuit(SchoolGirl* mm) { m_mm = mm; }; void GiveDolls() { std::cout << m_mm->GetName() << "送你洋娃娃" << std::endl; }; void GiveFlower() { std::cout << m_mm->GetName() << "送你鲜花" << std::endl; }; void GiveChocolate() { std::cout << m_mm->GetName() << "送你巧克力" << std::endl; };private: SchoolGirl* m_mm;};int main(){ SchoolGirl* jiaojiao = new SchoolGirl();//初始化要追求的对象 jiaojiao->SetName("李娇娇"); //事实上娇娇并不认识卓贾易 Pursuit* zhuojiayi = new Pursuit(jiaojiao); zhuojiayi->GiveChocolate(); zhuojiayi->GiveDolls(); zhuojiayi->GiveFlower(); delete jiaojiao; delete zhuojiayi; return 0;}

               2)小菜代理第二版

                  缺点:也不是让戴励自己亲自追求,不符合题意。

 

#include 
class SchoolGirl //要追的女孩 {public: void SetName(std::string str)//名字 { m_Name = str; }; std::string GetName(void) //获取女孩名字 { return m_Name; };private: std::string m_Name;};class Proxy//代理类,其实是戴励 {public: Proxy(SchoolGirl* mm) { m_mm = mm; }; void GiveDolls() { std::cout << m_mm->GetName() << "送你洋娃娃" << std::endl; }; void GiveFlower() { std::cout << m_mm->GetName() << "送你鲜花" << std::endl; }; void GiveChocolate() { std::cout << m_mm->GetName() << "送你巧克力" << std::endl; };private: SchoolGirl* m_mm;};int main(){ SchoolGirl* jiaojiao = new SchoolGirl(); jiaojiao->SetName("李娇娇"); Proxy* daili = new Proxy(jiaojiao); daili->GiveChocolate(); daili->GiveDolls(); daili->GiveFlower(); return 0;}

 

                   3)小菜第三版

                    改进:添加接口,让一个对象实现接口,代理负责运用接口。

                    实现:代理同样实现接口,只是代理实现接口的时候实际上是调用实际实现者的方法。

 

#include 
class SchoolGirl //要追的女孩 {public: void SetName(std::string str)//名字 { m_Name = str; }; std::string GetName(void) //获取女孩名字 { return m_Name; };private: std::string m_Name;};class GiveGift //送礼物接口(抽象函数就是接口) { virtual void GiveDolls(void) = 0; virtual void GiveFlower(void) = 0; virtual void GiveChocolate(void) = 0;};class Pursuit :public GiveGift//追求者去实现礼物接口{public: Pursuit(SchoolGirl* mm) { m_mm = mm; }; void GiveDolls() { std::cout << m_mm->GetName() << "送你洋娃娃" << std::endl; }; void GiveFlower() { std::cout << m_mm->GetName() << "送你鲜花" << std::endl; }; void GiveChocolate() { std::cout << m_mm->GetName() << "送你巧克力" << std::endl; };private: SchoolGirl* m_mm;};class Proxy :public GiveGift//代理类(也去实现送礼物接口,实际上是调用追求者的方法) {public: Proxy(SchoolGirl* mm) { m_gg = new Pursuit(mm); }; ~Proxy() { if (m_gg != NULL) { delete m_gg; m_gg = NULL; } }; void GiveDolls() { m_gg->GiveDolls(); }; void GiveFlower() { m_gg->GiveFlower(); }; void GiveChocolate() { m_gg->GiveChocolate(); };private: Pursuit* m_gg;};int main(){ SchoolGirl* jiaojiao = new SchoolGirl(); jiaojiao->SetName("李娇娇"); Proxy* daili = new Proxy(jiaojiao); daili->GiveChocolate(); daili->GiveDolls(); daili->GiveFlower(); return 0;}

 

三,代理模式的经典模板

 

     

class Subject{public:	virtual void Request(void) = 0;};class RealSubject : public Subject{public:	void Request(void)	{		std::cout << "真实的请求" << std::endl;	};};class Proxy : public Subject{public:	Proxy()		:m_realSubject(NULL)	{	}	void Request(void)	{		if (m_realSubject == NULL)		{			m_realSubject = new RealSubject();		}		m_realSubject->Request();	};private:	RealSubject* m_realSubject;};int main(){	Proxy* daili = new Proxy();	daili->Request();	delete daili;	return 0;}

 

 

 

转载于:https://www.cnblogs.com/secbook/archive/2012/06/22/2654990.html

你可能感兴趣的文章
真集群与伪集群的区别
查看>>
Note 387206.1 ORA-15041: ASM diskgroup with unlike disks sizes
查看>>
成都国税打造全能“电子税务局”
查看>>
[转载] 孙子兵法——01 始计第一
查看>>
python实现float/double的0x转化
查看>>
搭建Git服务器
查看>>
C#使用Xamarin开发可移植移动应用(5.进阶篇显示弹出窗口与通讯中心)附源码
查看>>
修改cmd路径方法 成功
查看>>
Long-Polling, Websockets, SSE(Server-Sent Event), WebRTC 之间的区别
查看>>
【总结整理】关于块级元素和行级元素
查看>>
通过查看编码映射表确定编码类型
查看>>
用python编写简易登录接口
查看>>
完成评论功能
查看>>
Alter的用法(添加字段,删除字段,修改字段名)
查看>>
MVC数据库连接
查看>>
解决UIScrollView 的点击事件
查看>>
java反射快速入门(一)
查看>>
Spring Boot 特性以及代码模板实例
查看>>
Linux signal 那些事儿(2)【转】
查看>>
Linux进程的创建函数fork()及其fork内核实现解析【转】
查看>>