代理模式Proxy Pattern

  • 代理模式
    • 1、背景
    • 2、定义
    • 3、特征
    • 4、应用场景
    • 5、实验案例
  • 参考

代理模式

1、背景

假如说我现在想租一间房子,虽然我可以自己去找房源,做卫生检测等一系列的房屋租赁流程,但是这确实太浪费我得时间和精力了。我只是想租一间房而已为什么我还要额外做这么多事呢?于是我就通过中介公司来租房,他们来给我找房源,我只是负责选择自己喜欢的房子,然后付钱就可以了。

为什么要用代理模式?

  • 1、中介隔离作用: 在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
  • 2、开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。
    • 代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。
    • 代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。
    • 真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

2、定义


UML关系图说明:

  • 继承关系(is a):实线、空三角箭头 ,Real SubjectProxy继承Subject
  • 聚合(has a):实线、菱形,菱形指向整体,整体包含部分,这里Proxy是整体,Real Subject是部分。

定义:

由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

  • 1、抽象角色(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  • 2、真实角色(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • 3、代理角色(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

3、特征

代理模式的主要优点有:

  • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
  • 代理对象可以扩展目标对象的功能;
  • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;

其主要缺点是:

  • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
  • 增加了系统的复杂度;

4、应用场景

  • 1、远程代理。
    为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。这个不同的地址空间可以是在本机器上,也可以在另一台机器中。
  • 2、虚拟代理:根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象,使其只有在真正需要时才被创建。
    • 有些图形对象的创建开销很大。但是打开文档必须很迅速,因此我们在打开文档时应避免一次性创建所有开销很大的对象。这里就可以运用代理模式,在打开文档时,并不打开图形对象,而是打开图形对象的代理以替代真实的图形。
  • 3、Copy-on-Write 代理。
    • 它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。
  • 4、保护(Protect or Access)代理。
    • 控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
  • 5、Cache代理。
  • 6、防火墙(Firewall)代理。
    • 为某一个目标的操作结果提供临时存储空间,以便其他客户的可以共享访问,有点缓存的味道。
  • 7、同步化(Synchronization)代理。
    • 可以让几个用户同时访问同一个对象而不产生冲突。
  • 8、智能引用(Smart Reference)代理。
    • 是指当调用真实对象时,代理处理另外一些事,比如记录对此对象的调用次数等。

5、实验案例

案例1

#include <iostream>
using namespace std;class Subject { // Subject类定义了RealSubject和Proxy的公用接口,这样就在任何使用RealSubject的地方都可以用Proxy
public:virtual void Request() = 0;virtual ~Subject() {}
};class RealSubject : public Subject { // RealSubject类,定义了Proxy所代表的真实实体
public:void Request() { cout << "RealSubject" << endl; }
};class Proxy : public Subject { // Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来代替实体
private:RealSubject* realSubject;
public:void Request() {if (realSubject == NULL) realSubject = new RealSubject();realSubject->Request();}
};int main() {Proxy* p = new Proxy();p->Request(); // RealSubjectdelete p;return 0;
}

2、大话设计模式案例

#include<iostream>
#include<string>
class SchoolGirl {private:std::string name;
public:void setName(std::string name) {this->name = name;}std::string getName() {return name;}
};//接口
class IGiveGift {public:virtual void GiveDolls() {};virtual void GiveFlowers() {};virtual void GiveChocolate() {};};
//  真正的追求者
class Pursuit :public IGiveGift {private:SchoolGirl* realPursuit;
public:Pursuit(SchoolGirl* realPursuit) {this->realPursuit = realPursuit;}void GiveDolls() {std::cout << realPursuit->getName() << " give u Dolls" << std::endl;}void GiveFlowers() {std::cout << realPursuit->getName() << " give u Flowers" << std::endl;}void GiveChocolate() {std::cout << realPursuit->getName() << " give u Chocolates" << std::endl;}
};//代理者
class Proxy :public IGiveGift {private:Pursuit* proxyPursuit;//OBJ
public:Proxy(SchoolGirl* realPursuit) {proxyPursuit = new Pursuit(realPursuit);}void GiveDolls() {proxyPursuit->GiveDolls();}void GiveFlowers() {proxyPursuit->GiveFlowers();}void GiveChocolate() {proxyPursuit->GiveChocolate();}
};void main() {SchoolGirl* jiaojiao = new SchoolGirl();jiaojiao->setName("lijiaojiao");Proxy* proxy = new Proxy(jiaojiao);proxy->GiveDolls();proxy->GiveFlowers();proxy->GiveChocolate();delete jiaojiao;jiaojiao = NULL;delete proxy;proxy = NULL;system("pause");}


3、虚拟代理

// 抽象类
class Image
{
public : Image(std::string name) : m_name(name){ } virtual ~Image( ){ } virtual void Show( ) = 0;      // 显示文档的函数  protected : std::string m_name;       // 文档名
}; // 大型实体类
class BigImage : public Image
{
public : BigImage(std::string name) : Image(name){ } virtual ~BigImage( ){ } void Show( ) { std::cout <<"This is Big Image..." <<std::endl; }
}; // 大型图片代理器
class BigImageProxy : public Image
{
public : BigImageProxy(std::string name) :Image(name), m_bigImage(NULL){ } virtual ~BigImageProxy( ) { delete m_bigImage; } void Show( ) { if(this->m_bigImage == NULL) { m_bigImage = new BigImage(this->m_name); } m_bigImage->Show( ); } private : BigImage *m_bigImage;
}; // 客户端代码
int main( )
{ Image *Image = new BigImageProxy("Image.txt"); Image->Show( ); delete Image; return 0;
}

参考

1、https://www.cnblogs.com/daniels/p/8242592.html
2、http://c.biancheng.net/view/1359.html
3、https://blog.csdn.net/hguisu/article/details/7542143
4、https://www.cnblogs.com/zle1992/p/9753359.html
5、《大话设计模式》

设计模式——代理模式(Proxy Pattern)之为别人做嫁衣相关推荐

  1. 设计模式——代理模式(C++)——为别人做嫁衣

    代理模式: 为其他对象提供一种代理以控制对这个对象的访问 #include <iostream>using namespace std;class SchoolGirl { public: ...

  2. 设计模式-代理模式(Proxy Pattern)

    设计模式-代理模式(Proxy Pattern) 文章目录 设计模式-代理模式(Proxy Pattern) 一.定义 二.概念解释 三.场景 四.实现 1.类图 2.代码实现 五.小结 六.动态代理 ...

  3. Java24种设计模式(第二种)--代理模式(Proxy Pattern)

    Java24种设计模式 (第二种) 一.代理模式(Proxy Pattern) 模式逻辑: 什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道 被代理人能做哪些事 ...

  4. 二十四种设计模式:代理模式(Proxy Pattern)

    代理模式(Proxy Pattern) 介绍 为其他对象提供一个代理以控制对这个对象的访问. 示例 有一个Message实体类,某对象对它的操作有Insert()和Get()方法,用一个代理来控制对这 ...

  5. 《大话设计模式》之--第7章 为别人做嫁衣----代理模式

    第7章 为别人做嫁衣----代理模式 7.1为别人做嫁衣 "小菜,今天见这个叫娇娇的美女见得如何呀?"大鸟一回家来就问小菜. "唉,别提了,人家是有男朋友的." ...

  6. js设计模式——代理模式proxy

    什么是代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问. (可以想象一下明星与经纪人的关系,明星是请求的本体,经纪人就是代理proxy) 如何实现代理模式 代理对象内部含有对本 ...

  7. 设计模式(结构型)之代理模式(Proxy Pattern)

    PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...

  8. JAVA设计模式Design Pattern→单例模式Singleton Pattern、工厂模式Factory Pattern、代理模式Proxy Pattern

    私有化构造函数的类可以提供相应的 "接口"(一般就是静态方法)来返回自己的唯一实例供外部调用,像这样的确保只生成一个实例的模式被称作单例模式. 工厂模式,一个模型,用来大规模的生产 ...

  9. C++设计模式--代理模式(Proxy)

    前言 C++相对其他编程语言来说算是比较难的了,相关知识点非常多,并且有些概念理解起来比较困难,对于初学者来说可能会感觉到非常痛苦.随着项目难度的升级,需要不断地优化框架从而使整个结构更具有扩展性,那 ...

最新文章

  1. 什么数字万用表可以测量噪声?
  2. 循环节长度 java,第六届蓝桥杯java试题-循环节长度
  3. php运行代码运行退出为0,php – Selenium测试用例返回进程以退出代码0结束
  4. jvm内存收集器总结(图片)
  5. 无线数传模块SI4463、SI4438、SI4432方案无线通信比对
  6. 美国远程MBA全面占领MBA市场
  7. 【敏感度,查询,裁剪代码实现】差分隐私代码实现系列(六)
  8. Linux技术学习要点,您掌握了吗---初学者必看
  9. 在sqlyog进行数据库的备份_狂神说MySQL07:权限及如何设计数据库
  10. python gil锁_python--GIL锁
  11. HTML5缓存之 WebStorage
  12. Html——小米商城网页实战(一)
  13. PR模板 红黑大气手机竖屏竖版时尚短视频宣传抖音PR模板
  14. Android微信emoji表情,Android 软键盘和emoji表情切换方案,和微信几乎一样的体验...
  15. hdb3编码规则波形_求HDB3码编码后波形,编码后功率谱密度图形,求解啊
  16. 视频直播的购物平台,网站,app
  17. TFT和STN液晶区别
  18. 单击Artwork时没有弹窗的问题
  19. Mysql 新增分区,删除分区,合并分区
  20. 鸿蒙系统电视评测,荣耀智慧屏体验评测:电视只是小功能,鸿蒙系统才是真亮点...

热门文章

  1. 设置窗口Qt example 之 简易字典
  2. 【vue】vue组件之图文编辑
  3. 安卓图片手势缩放、旋转、移动
  4. mysql 乱码问题详解
  5. vos3000如何指定某个对接网关走某个落地网关
  6. 安徽省谷歌地球高程DEM等高线下载
  7. u盘数据损坏怎么恢复?
  8. 视频中的水印怎么去掉,去水印哪个软件好
  9. 爬虫数据解析的三种方式
  10. 挑选智能音箱时,首选“智能”还是“音质”?这篇文章给你答案