设计模式-04 设计模式-Proxy Pattern 代理模式

设计模式-04 设计模式-Proxy Pattern 代理模式
 

1.定义

代理模式 为一个对象提供一个代理或占位符,以便控制对该对象的访问和操作。代理可以拦截并修改对目标对象的调用,从而实现以下目的:

控制访问:限制对敏感或昂贵对象的访问,只允许经过身份验证或授权的用户访问。
延迟实例化:推迟创建昂贵或耗时的对象,直到真正需要时才创建。
提供额外的功能(日志记录,监控):在不修改目标对象的情况下,向目标对象添加额外的功能,例如日志记录、缓存或安全检查。
缓存功能:对于昂贵的对象,可以减少重复创建,减少调用真实对象的次数

       

+--------------+|              ||   Interface  ||              |+--------------+|v+--------------+            +--------------+|   Proxy       |  ----|>   |   Concrete   ||   Object      |           |  Object      |+--------------+            +--------------+
2.内涵

代理模式 结构,代理模式包含以下角色:

  • Subject(目标):被代理的真实对象。
  • Proxy(代理):提供对目标对象的代理或占位符。
  • Client(客户端):使用代理来访问目标对象。

常用例子:

一个代理模式的例子是远程代理,它可以代表远程服务器上的对象。远程代理拦截对本地对象的调用,并将其转发到远程服务器上的实际对象。这允许客户端与远程对象交互,而无需直接访问远程服务器。

此外开源软件里面用的此模式的场景:

  • Mockito:使用代理模式创建模拟对象,用于单元测试。
  • Javassist:使用代理模式动态生成字节码,用于增强和修改现有类。
  • ASM:使用代理模式在字节码级别增强和修改类。
3.案例

一个简单使用 代理模式的c++ demo 

#include <iostream>using namespace std;class Image {
public:virtual void display() = 0;
};class RealImage : public Image {
private:std::string filename;public:RealImage(const std::string& filename) : filename(filename) {std::cout << "加载 image: " << filename << std::endl;}void display() override {std::cout << "显示 image: " << filename << std::endl;}
};class ImageProxy : public Image {
private:RealImage* realImage;std::string filename;public:ImageProxy(const std::string& filename) : filename(filename), realImage(nullptr) {}void display() override {if (nullptr == realImage) {realImage = new RealImage(filename);  // 如果有加载这次就不加载}realImage->display();}
};int main() {Image* image = new ImageProxy("example.jpg");image->display(); // 具有缓存功能image->display();delete image; // Clean upreturn 0;
}
4.最佳实践


代理模式最佳实践:

明确代理目的:清楚地定义代理的职责和它要解决的问题。
将代理与目标对象解耦:代理不应该直接依赖于目标对象的具体实现。使用抽象接口或基类来表示目标对象,以便代理可以与不同的目标对象一起使用。
保持代理与目标对象同步:如果目标对象的状态发生变化,代理也应该相应地更新。
避免代理循环:确保代理不会直接或间接地引用自身,否则会导致无限循环。
使用虚拟代理来延迟实例化:只在需要时才创建目标对象,以提高性能。
考虑使用 AOP(面向方面编程):AOP 框架可以简化代理的创建和管理,尤其是在需要向多个对象添加类似功能的情况下。
谨慎使用代理:过度使用代理可能会降低性能并增加代码复杂性。只在真正需要的时候使用代理。
测试代理:编写测试以验证代理的正确行为,包括边界条件和异常情况。

此外以下也需要重点关注:

使用设计模式来增强代理:例如,可以使用工厂模式来创建代理,或者使用单例模式来确保只有一个代理实例。
考虑使用库或框架来实现代理:有许多库和框架(如 Spring AOP)提供开箱即用的代理实现。
记录代理的用途和限制:在代码中清楚地记录为什么使用代理以及代理的限制。


5.总结

代理模式在 C++中的应用是一种有价值的工具,可以增强应用程序的控制力和效率。通过使用代理,可以实现延迟初始化、访问控制、日志记录和缓存,从而提高代码的性能和可维护性。它允许你在不改变类结构的情况下为类添加额外的功能层。在恰当应用时,代理模式可以成为你设计模式工具箱中的一个强有力武器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/7864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IP证书能免费申请吗

IP SSL证书是一种数字证书&#xff0c;用于保护网络服务器和网络浏览器之间的通信。该证书是一种主要保护公网IP地址的专属信任SSL证书。 IP类型的SSL证书对于直接用IP地址传输数据的技术人员来说&#xff0c;十分重要&#xff01;无论是防洪还是防劫持还是数据加密都起到了关…

QML进阶(十四) Model-View-Delegate视图框架

文章目录 数据模型(Model)C++数据模型XmlListModelRepeater模型视图框架(View)ListViewTableViewGridViewPathViewMVC(Model-View-Controller)模式将视图系统拆分为模型、视图、控制器三部分,每个部分都相对独立职责单一。模型(model)负责管理视图的数据并对外提供服务。视图(…

asp.net成绩查询系统

说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net架构和sql server数据库 功能模块&#xff1a; asp.net成绩查询系统 学生功能有查看成绩和修改账号密码等 后台管理员可以进行用户管理 管理员添加管理员查询注…

重学计算机网络

一、应用层 1. http1.0 与 http2.0 的区别 有两点 1是持久化&#xff0c; 这个持久化并不是磁盘的持久化&#xff0c;而是tcp连接建立的持久化。 HTTP/1.0默认情况下使用短连接&#xff0c;即每个请求/响应都会关闭连接。这意味着每次请求都需要重新建立连接&#xff0c;增…

ADS基础教程10-多态性(动态模型选择)

目录 一、多态性定义二、操作步骤&#xff11;.模型建立&#xff12;.模型选择&#xff13;.执行仿真 一、多态性定义 ADS中支持一个Symbol中&#xff0c;可以同时存在多个子图。在仿真时可以动态选择不同的子图继续宁仿真。 二、操作步骤 &#xff11;.模型建立 在上一章A…

贪心算法应用例题

最优装载问题 #include <stdio.h> #include <algorithm>//排序int main() {int data[] { 8,20,5,80,3,420,14,330,70 };//物体重量int max 500;//船容最大总重量int count sizeof(data) / sizeof(data[0]);//物体数量std::sort(data, data count);//排序,排完数…

echarts tooltip 内容太多,超出范围显示不全问题,亲测有效

参考文章&#xff1a;echarts tooltip显示不全问题 在项目里面的tooltip数据特别多&#xff0c;显示不全问题&#xff08;有下面几种方法&#xff0c;选择最适合自己的&#xff09;&#xff1a; 1、如果盒子还够大&#xff0c;只是tooltip飘到上面或者下面被覆盖住了&#xff…

你用过最好用的AI工具有哪些?

你用过最好用的AI工具有哪些&#xff1f; 一、常用AI工具 当今人们在日常生活和工作中经常使用的AI工具包括&#xff1a; 智能语音助手&#xff08;如Siri、Google Assistant、Alexa&#xff09;&#xff1a;这些语音助手能够通过语音指令执行各种任务&#xff0c;如设置提醒…

Spring Cloud 整合Sentinel

1、引入依赖 版本说明 alibaba/spring-cloud-alibaba Wiki GitHub 父pom <spring.cloud.version>Hoxton.SR12</spring.cloud.version> <spring.cloud.alibaba.version>2.2.10-RC1</spring.cloud.alibaba.version>Sentinel应用直接引用starter <…

Python做自动化测试必知必会思维导图

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

Meta最新研究: Flash Attention 为何是系统性能瓶颈?

I. 引言 随着机器学习趋向于更大和更复杂的模型,模型训练过程变得越来越计算和资源密集。生成式AI的出现进一步推动了模型开发的边界,大型语言模型(LLMs)通常在数百或数千个GPU上训练数月。以LLaMA2的70-B参数模型为例,需要1,720,320 GPU小时来训练。对于如此长的训练作业,训练…

独立开发,做的页面不好看?我总结了一些工具与方法

前言 我有时候会自己开发一些项目,但是不比在公司里面,自己开发项目的时候没有设计稿,所以做出来的页面比较难看。 开发了几个项目之后,我也总结了以下的一些画页面的资源或者方法,希望对大家有帮助~ 颜色&字体 这一部分主要参考的是antd的方案,主要包括颜色与字…

Kubernetes核心概念基本操作

1.1 Namespace命名空间 1.1.1 Namespace核心概念 Kubernetes 的 Namespace&#xff08;命名空间&#xff09;是一种用于创建逻辑隔离分区的机制&#xff0c;它的主要作用是用来实现多套环境的资源隔&#xff0c;它允许用户在同一个物理集群中模拟出多个虚拟集群的效果。以下是…

JAVA面向对象高级部分

内部类 内部类的四种形式 内部类概述、成员内部类 代码示例 创建对象的格式 通过对象名访问内部类方法 若内外部类的成员变量名冲突&#xff0c;如何在内部类分别访问外部成员变量。 总结 静态内部类 代码示例 访问静态内部类的方法 不能在静态内部类中访问实例成员变量 …

【LAMMPS学习】八、基础知识(5.8)LAMMPS 中热化 Drude 振荡器教程

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

PHP源码_众筹商城

众筹商城源码 众筹商品平台 商城加共识元富之路 网上商城众筹 前端是编译后的&#xff0c;后端PHP&#xff0c;带商城 运行截图 源码贡献 https://githubs.xyz/boot?app39 部分数据库表 CREATE TABLE ti_shopro_store (id int(11) NOT NULL AUTO_INCREMENT COMMENT ID,nam…

JDK动态代理和Cglib动态代理区别

1.如果目标类实现了接口&#xff0c;将会使用JDK动态代理&#xff0c;否则会使用Cglib动态代理; 2.JDK代理使用自己的字节码生成工具生成代理对象&#xff0c;而Cglib会使用ASM字节码生成工具去生成; 3.JDK动态代理是通过反射的方式去实现代理对象的所有方法&#xff0c;通过…

PXE批量安装

系统装机的三种引导方式 u盘光盘网络装机 光盘&#xff1a; 1.类似于usb模式 2.刻录模式 系统安装过程 加载boot loader Boot Loader 是在操作系统内核运行之前运行的一段小程序。通过这段小程序&#xff0c;我们可以初始化硬件设备、建立内存空间的映射图&#xff0c;从…

静态分析-RIPS-源码解析记录-01

token流扫描重构部分&#xff0c;这一部分主要利用php的token解析api解析出来的token流&#xff0c;对其中的特定token进行删除、替换、对于特定的语法结构进行重构&#xff0c;保持php语法结构上的一致性 解析主要在lib/scanner.php中通过Tokenizer这个类来实现,也就是在main…

linux或ubuntu环境下需要自行安装vivado USB Program下载程序驱动

如果在linux或ubuntu环境下&#xff0c;不安装驱动是无法下载FPGA程序的。在linux或ubuntu环境下安装程序不要自动安装。 johnjohn-wang:~/vitis2021.2/Vivado/2021.2/data/xicom/cable_drivers/lin64/install_script/install_drivers$ sudo ./install_drivers