中国建设银行行号查询网站/app推广地推接单网
文章目录
- 代理模式(Proxy Pattern)
- 1. 概念
- 2. 模式结构
- 3. UML 类图
- 4.实现方式
- C# 示例
- 步骤1:定义主题接口
- 步骤2:实现真实主题
- 步骤3:实现代理类
- 步骤4:客户端使用代理模式
- 输出结果:
- Java 示例
- 步骤1:定义主题接口
- 步骤2:实现真实主题
- 步骤3:实现代理类
- 步骤4:客户端使用代理模式
- 输出结果:
- 5. 代理模式的类型
- 5.1 虚拟代理
- 5.2 远程代理
- 实现步骤
- 步骤1:定义主题接口
- 步骤2:实现真实主题
- 步骤3:实现远程代理
- 步骤4:客户端使用远程代理
- 5.3 保护代理
- 5.4 智能代理
- 实现步骤
- 步骤1:定义主题接口
- 步骤2:实现真实主题
- 步骤3:实现智能代理
- 步骤4:客户端使用智能代理
- 5.5 应用场景
- 6. 优点
- 7. 缺点
- 8. 代理模式应用场景
- 9.代理模式变体
- 9.1 虚拟代理(Virtual Proxy)
- 实现步骤
- 步骤1:定义主题接口
- 步骤2:实现真实主题
- 步骤3:实现虚拟代理
- 步骤4:客户端使用虚拟代理
- 应用场景
- 9.2 保护代理(Protection Proxy)
- 实现步骤
- 步骤1:定义主题接口
- 步骤2:实现真实主题
- 步骤3:实现保护代理
- 步骤4:客户端使用保护代理
- 应用场景
- 9.3 缓存代理(Caching Proxy)
- 实现步骤
- 步骤1:定义主题接口
- 步骤2:实现真实主题
- 步骤3:实现缓存代理
- 步骤4:客户端使用缓存代理
- 应用场景
- 10.总结
代理模式(Proxy Pattern)
1. 概念
代理模式是一种结构型设计模式,它为另一个对象提供了一个替身或占位符,以控制对该对象的访问。代理可以代替原对象执行操作、控制访问权限、延迟加载等。这种模式的关键在于代理对象和被代理对象实现相同的接口,以确保它们可以互换。
2. 模式结构
代理模式的核心角色包括:
- 主题(Subject):定义了代理对象和真实对象的公共接口。
- 真实主题(RealSubject):实际的业务逻辑类,代理对象通过控制对它的访问来扩展功能。
- 代理(Proxy):持有对
RealSubject
的引用,并可以在调用前后对其操作进行控制或扩展。
3. UML 类图
4.实现方式
C# 示例
步骤1:定义主题接口
public interface ISubject
{void Request();
}
步骤2:实现真实主题
public class RealSubject : ISubject
{public void Request(){Console.WriteLine("RealSubject: Handling Request.");}
}
步骤3:实现代理类
public class Proxy : ISubject
{private RealSubject _realSubject;public void Request(){if (_realSubject == null){_realSubject = new RealSubject();}Console.WriteLine("Proxy: Controlling access before forwarding the request.");_realSubject.Request();}
}
步骤4:客户端使用代理模式
class Program
{static void Main(string[] args){ISubject proxy = new Proxy();proxy.Request();}
}
输出结果:
Proxy: Controlling access before forwarding the request.
RealSubject: Handling Request.
Java 示例
步骤1:定义主题接口
public interface Subject {void request();
}
步骤2:实现真实主题
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}
步骤3:实现代理类
public class Proxy implements Subject {private RealSubject realSubject;@Overridepublic void request() {if (realSubject == null) {realSubject = new RealSubject();}System.out.println("Proxy: Controlling access before forwarding the request.");realSubject.request();}
}
步骤4:客户端使用代理模式
public class Main {public static void main(String[] args) {Subject proxy = new Proxy();proxy.request();}
}
输出结果:
Proxy: Controlling access before forwarding the request.
RealSubject: Handling request.
5. 代理模式的类型
5.1 虚拟代理
虚拟代理用于控制资源密集型对象的实例化,常用于延迟加载(Lazy Initialization)场景。代理类在实际使用时才实例化真实对象,从而节省系统资源。
- 示例:当一个图像很大且加载时间较长时,使用虚拟代理可以延迟图像的加载,只有当图像真正需要显示时才进行加载。
public class ImageProxy : IImage
{private RealImage _realImage;private string _fileName;public ImageProxy(string fileName){_fileName = fileName;}public void Display(){if (_realImage == null){_realImage = new RealImage(_fileName);}_realImage.Display();}
}
5.2 远程代理
远程代理为位于不同地址空间的对象(如通过网络通信的对象)提供代理。客户端通过代理访问远程服务器上的对象,而不直接处理复杂的通信逻辑。
- 示例:当客户端需要访问远程的Web服务或数据库时,使用远程代理可以将网络通信的复杂性隐藏在代理类中。
实现步骤
步骤1:定义主题接口
与真实对象和代理对象共享相同的接口,以便客户端可以通过代理访问。
public interface Subject {void request();
}
步骤2:实现真实主题
真实对象实现了主题接口,并包含了实际的业务逻辑。
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}
步骤3:实现远程代理
远程代理通常会处理网络通信的细节,比如使用HTTP、Socket等。它会将请求发送到远程服务器,接收响应并返回给客户端。
import java.io.*;
import java.net.*;public class RemoteProxy implements Subject {private String serverAddress;public RemoteProxy(String serverAddress) {this.serverAddress = serverAddress;}@Overridepublic void request() {try {Socket socket = new Socket(serverAddress, 8080);PrintWriter out = new PrintWriter(socket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));out.println("Request from Remote Proxy");String response = in.readLine();System.out.println("Response from Real Subject: " + response);in.close();out.close();socket.close();} catch (IOException e) {e.printStackTrace();}}
}
步骤4:客户端使用远程代理
客户端通过远程代理调用真实主题的功能。
public class Client {public static void main(String[] args) {Subject proxy = new RemoteProxy("localhost");proxy.request();}
}
服务器端示例
服务器端接收请求并返回响应:
import java.io.*;
import java.net.*;public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(8080);System.out.println("Server is running...");while (true) {Socket clientSocket = serverSocket.accept();PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));String request = in.readLine();System.out.println("Received: " + request);out.println("Handled by Real Subject");in.close();out.close();clientSocket.close();}}
}
5.3 保护代理
保护代理用于控制对原始对象的访问,主要是限制某些客户端的权限。代理会根据访问者的权限决定是否可以访问真实对象。
- 示例:在访问控制系统中,代理可以根据用户的角色决定是否授予对特定资源的访问权。
public class ProtectedProxy : ISubject
{private RealSubject _realSubject;private string _userRole;public ProtectedProxy(string userRole){_userRole = userRole;}public void Request(){if (_userRole == "Admin"){_realSubject = new RealSubject();_realSubject.Request();}else{Console.WriteLine("Access Denied: You don't have permission to perform this operation.");}}
}
5.4 智能代理
智能代理可以在真实对象操作的前后执行一些附加操作,例如记录日志、统计调用次数、缓存结果等。
- 示例:在Web应用程序中,智能代理可以用于记录每个请求的处理时间。
public class LoggingProxy : ISubject
{private RealSubject _realSubject;public void Request(){Console.WriteLine("Logging: Before executing the request.");if (_realSubject == null){_realSubject = new RealSubject();}_realSubject.Request();Console.WriteLine("Logging: After executing the request.");}
}
实现步骤
步骤1:定义主题接口
与之前相同,定义一个公共接口。
public interface Subject {void request();
}
步骤2:实现真实主题
实现主题接口的真实对象。
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("RealSubject: Handling request.");}
}
步骤3:实现智能代理
智能代理在调用真实对象的请求方法前后执行一些附加操作,比如记录日志或计算执行时间。
public class SmartProxy implements Subject {private RealSubject realSubject;public SmartProxy() {this.realSubject = new RealSubject();}@Overridepublic void request() {System.out.println("SmartProxy: Logging before request.");long startTime = System.currentTimeMillis();realSubject.request();long endTime = System.currentTimeMillis();System.out.println("SmartProxy: Logging after request. Execution time: " + (endTime - startTime) + " ms");}
}
步骤4:客户端使用智能代理
客户端通过智能代理调用真实主题。
public class Client {public static void main(String[] args) {Subject proxy = new SmartProxy();proxy.request();}
}
5.5 应用场景
远程代理
场景:在分布式系统中,客户端需要访问远程服务,远程代理负责处理网络通信和请求转发。
应用:RPC(远程过程调用)、RESTful API等场景。
智能代理
场景:需要对方法调用进行监控、统计或其他增强功能,智能代理可以提供附加的处理逻辑。
应用:日志记录、性能监控、缓存管理等场景。
6. 优点
- 控制对象访问:代理模式可以控制对真实对象的访问,添加权限控制、延迟加载、网络通信等功能。
- 节省系统资源:虚拟代理可以在对象真正需要时才创建,从而节省资源。
- 增强功能:代理可以在真实对象执行操作前后添加额外的功能,如日志记录、缓存等。
7. 缺点
- 增加复杂性:由于引入了代理类,系统变得更加复杂,增加了类的数量。
- 性能开销:代理可能导致额外的开销,特别是在处理远程调用或过度使用智能代理时。
8. 代理模式应用场景
- 远程代理:当需要访问远程对象时,可以使用远程代理隐藏通信的细节。
- 虚拟代理:当需要延迟加载资源密集型对象时,可以使用虚拟代理。
- 访问控制:当需要控制对某些资源或对象的访问权限时,保护代理是一个理想的选择。
- 性能优化:使用智能代理可以在不改变原有业务逻辑的情况下,优化性能或增加功能。
9.代理模式变体
9.1 虚拟代理(Virtual Proxy)
虚拟代理用于延迟加载资源密集型对象的实例化,直到需要时才创建真实对象。这样可以节省系统资源,避免不必要的开销。
实现步骤
步骤1:定义主题接口
public interface Image {void display();
}
步骤2:实现真实主题
public class RealImage implements Image {private String fileName;public RealImage(String fileName) {this.fileName = fileName;loadImageFromDisk();}private void loadImageFromDisk() {System.out.println("Loading " + fileName);}@Overridepublic void display() {System.out.println("Displaying " + fileName);}
}
步骤3:实现虚拟代理
public class ImageProxy implements Image {private RealImage realImage;private String fileName;public ImageProxy(String fileName) {this.fileName = fileName;}@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(fileName);}realImage.display();}
}
步骤4:客户端使用虚拟代理
public class Client {public static void main(String[] args) {Image image = new ImageProxy("test_image.jpg");image.display(); // 只在此处加载image.display(); // 直接显示,不再加载}
}
应用场景
- 适用于需要加载大型对象的场景,例如图像、视频等。
- 在图形界面应用中,通常使用虚拟代理来延迟加载图形组件。
9.2 保护代理(Protection Proxy)
保护代理控制对真实对象的访问,主要用于权限管理。它根据客户端的身份或角色决定是否允许访问真实对象。
实现步骤
步骤1:定义主题接口
public interface Document {void view();
}
步骤2:实现真实主题
public class RealDocument implements Document {@Overridepublic void view() {System.out.println("Viewing Document");}
}
步骤3:实现保护代理
public class ProtectionProxy implements Document {private RealDocument realDocument;private String userRole;public ProtectionProxy(String userRole) {this.userRole = userRole;}@Overridepublic void view() {if (userRole.equals("Admin")) {if (realDocument == null) {realDocument = new RealDocument();}realDocument.view();} else {System.out.println("Access Denied: You do not have permission to view this document.");}}
}
步骤4:客户端使用保护代理
public class Client {public static void main(String[] args) {Document doc = new ProtectionProxy("User");doc.view(); // Access DeniedDocument adminDoc = new ProtectionProxy("Admin");adminDoc.view(); // Access Granted}
}
应用场景
- 适用于敏感数据或操作,需要根据用户权限控制访问的场景。
- 在企业级应用中常见,用于控制对重要文档或资源的访问。
9.3 缓存代理(Caching Proxy)
缓存代理在调用真实对象的方法前检查是否已经缓存了结果。如果有,则直接返回缓存结果,否则调用真实对象并将结果存入缓存。
实现步骤
步骤1:定义主题接口
public interface Data {String fetchData();
}
步骤2:实现真实主题
public class RealData implements Data {@Overridepublic String fetchData() {return "Data from Real Data Source";}
}
步骤3:实现缓存代理
import java.util.HashMap;public class CachingProxy implements Data {private RealData realData;private HashMap<String, String> cache;public CachingProxy() {this.realData = new RealData();this.cache = new HashMap<>();}@Overridepublic String fetchData() {if (cache.containsKey("data")) {System.out.println("Returning cached data.");return cache.get("data");}String data = realData.fetchData();cache.put("data", data);return data;}
}
步骤4:客户端使用缓存代理
public class Client {public static void main(String[] args) {Data dataProxy = new CachingProxy();System.out.println(dataProxy.fetchData()); // First call fetches dataSystem.out.println(dataProxy.fetchData()); // Subsequent call returns cached data}
}
应用场景
- 适用于数据查询频繁但变化不大的场景,例如Web应用中的数据库查询结果。
- 可以显著提高性能,减少对真实数据源的调用次数。
10.总结
代理模式在控制对象访问和增强系统功能方面提供了很大的灵活性,且每种变体都有其独特的用处,需要根据需求进行选择和实施。
相关文章:

【软件设计】常用设计模式--代理模式
文章目录 代理模式(Proxy Pattern)1. 概念2. 模式结构3. UML 类图4.实现方式C# 示例步骤1:定义主题接口步骤2:实现真实主题步骤3:实现代理类步骤4:客户端使用代理模式输出结果: Java 示例步骤1&…...

生命与自由,抑郁的来源
在中国文学史上,有一句极其伟大的话,它点出了所有人痛苦的根源。它出自《我与地坛》,太阳它每时每刻即是夕阳也都是旭日,当他从这一段熄灭着走下山去,收尽苍凉参照之际,也正是它在另一端燃烧着爬上山巅布散…...

CTFHUB技能树之文件上传——双写后缀
开启靶场,打开链接: 直接指明是双写绕过方法 上传06shaungxie.php,内容如下: 这一步其实最好换成.png或者.jpg或者.gif这三个符合文件格式的要求后缀 用burp抓包改包: 将php改成pphphp后再“Forward”: 上传…...

SpringBoot整合HTTPS
文章目录 1_Https 的作用2_获取证书3_配置项4_配置类5_控制类6_启动类 1_Https 的作用 保护用户的隐私信息安全: 在 HTTP 网站数据以明文方式传输,客户的隐私极容易被盗取和泄露,而部署 SSL 证书,数据以 HTTPS 加密传输…...

LVGL-从入门到熟练使用
LVGL简介 LVGL( Light and Versatile Graphics Library )是一个轻量、多功能的开源图形库。 1、丰富且强大的模块化图形组件:按钮 、图表 、列表、滑动条、图片等 2、高级的图形引擎:动画、抗锯齿、透明度、平滑滚动、图层混合等…...

【MySQL数据库】MySQL读写分离
文章目录 读写分离概念读写分离的动机读写分离的适用场景主从复制与读写分离MySQL 读写分离原理MySQL读写分离的实现方式代表性程序 MySQL读写分离实验搭建 MySQL 读写分离Amoeba 服务器配置测试读写分离 问答 读写分离 概念 读写分离是为了优化数据库性能,通过将…...

深度学习:简单计算图的反向传播传递导数计算
问题: 太郎在超市买了2个100日元一个的苹果,消费税是10%,请计算支付金额。 反向传播使用与正方向相反的箭头(粗线)表示。反向传播传递“局部导数”,将导数的值写在箭头的下方。在这个例子中,反向…...

学习AJAX请求(初步)24.10.21-10.23
1.AJAX概念 AJAX Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。 AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。 虽然所有的AJAX请求都是HTTP请求,但并非所有的HT…...

初识算法——二分查找
1.概念 二分查找算法也称折半查找,是一种非常高效的工作于有序数组的查找算法。 需求:在有序数组 A A A 内,查找值 t a r g e t target target 如果找到返回索引如果找不到返回 − 1 -1 −1 前提给定一个内含 n n n 个元素的有序数组…...

深入剖析 Java Spring 中的 @Autowired、@Resource、@Qualifier、@Inject 注解:使用详解与注意事项
文章目录 Autowired:Spring 最常用的注解1. 作用与简介2. 使用示例3. 注意事项 Resource:按名称注入的利器1. 作用与简介2. 使用示例3. 注意事项 Qualifier:解决多 bean 注入问题1. 作用与简介2. 使用示例3. 注意事项 Inject:标准…...

ThingsBoard规则链节点:Delete Attributes节点详解
引言 删除属性节点简介 用法 含义 应用场景 实际项目运用示例 智能家居安全系统 物流跟踪解决方案 工业自动化生产线 结论 引言 ThingsBoard是一个开源的物联网平台,它提供了设备管理、数据收集与处理以及实时监控等功能。其中,规则引擎是其核心…...

关于作为面试官以及如何准备面试的一些心得
关于作为面试官以及如何准备面试的一些心得 一、面试官(我站在前端角度来说) 当作为这样身份的时候,我想第一步应该是自己梳理一些从简到难、从点到面的问题 CSS - JS - 框架 - 项目 从这四个角度出发,一步一步的引导面试者的思…...

Bean对象 和 普通对象 的区别
Bean对象 和 普通对象 的区别 前言Bean的概念与new创建的对象的区别Spring Bean的优势两者使用的关键点总结 前言 在Spring框架中,我们通常将Spring容器管理的对象称为“Bean”或“Bean对象”。而通过new关键字创建的对象则被称为“对象”或“普通对象”。 Bean的…...

lego-loam featureAssociation 源码注释(二)
咱们接着往下看initializationValue();!!! FeatureAssociation():nh("~"){subLaserCloud nh.subscribe<sensor_msgs::PointCloud2>("/segmented_cloud", 1, &FeatureAssociation::laserCloudHandler, this);s…...

Claude 3.5 的六大应用场景
Claude 3.5 的六大应用场景 随着人工智能技术的飞速发展,Claude 3.5 已经成为一款强大的语言模型工具,在多个领域展现了其卓越的应用潜力。本文将通过CSDN格式,介绍Claude 3.5在六大主要领域的实际应用场景,帮助开发者和企业更好…...

进程线程知识总结
1. 程序什么时候应该使用线程,什么时候单线程效率高 使用线程:在I/O密集型或高并发的场景,例如网络服务、文件读写等。通过多线程可以同时处理多个任务,提高利用率。单线程效率高:在CPU密集型任务中,当任务…...

Rsync数据复制/备份服务应用
文章目录 1. rsync概述1.1 什么是Rsync1.2 rsync的功能1.3 rsync 的功能特性1.4 Rsync 增量复制原理1.5 生产场景架构集群备份方案 2. Rsync工作方式介绍与实践2.1 本地数据传输模式2.1.1 本地数据传输模式语法2.1.2 本地数据传输模式实践 2.2 远程Shell 数据传输模式2.2.1 远程…...

如何为自己的跨境网站添加多国语言翻译功能及推荐起尔网定制与插件开发
如何为自己的跨境网站添加多国语言翻译功能及推荐起尔网定制与插件开发 在全球化的浪潮下,跨境电商成为越来越多企业拓展国际市场的重要途径。然而,语言障碍成为了一个不可忽视的问题。为了更好地服务全球用户,为自己的跨境网站添加多国语言…...

安全见闻(3)——开阔眼界,不做井底之蛙
内容预览 ≧∀≦ゞ 安全见闻三:脚本程序与病毒声明导语脚本语言BAT/PowerShell脚本木马与宏病毒脚本病毒BIOS病毒 结语 安全见闻三:脚本程序与病毒 声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只…...

MySQL 的意向锁(Intention Locks)原理详解
1. 背景:为什么需要意向锁? MySQL 中意向锁的主要作用是用于支持行级锁与表级锁的并存,特别是在 InnoDB 存储引擎中。InnoDB 提供了行级锁,而在某些场景下,数据库系统仍需要对整张表加锁,例如 LOCK TABLES …...

31个省份农业科技水平(农业技术创新或农业科技专利数据)2010-2022年
一、测算方式:参考C刊《湖北大学学报(哲学社会科学版)》张金鑫(2020)老师的做法,采用农业( 农林牧渔业) 三类专利总和来衡量农业技术创新 二、资料范围:31个省份,403个观测值,已经整理成面板数…...

Python代码执行失败问题及解决方案
目录 一、Python代码执行失败的原因 二、常见的Python错误类型 1. 语法错误(SyntaxError) 2. 运行时错误(RuntimeError) 3. 类型错误(TypeError) 4. 导入错误(ImportError) 5…...

Java 遗传算法
遗传算法(Genetic Algorithm, GA)是一种基于自然选择和遗传学原理的优化算法,用于求解复杂的搜索和优化问题。在Java中实现遗传算法通常包括以下几个步骤: 初始化种群:生成一组随机解作为初始种群。适应度评估&#x…...

C++ (一) 基础语法
基础语法:C的开胃小菜 欢迎来到C的世界,这里是编程的盛宴,也是逻辑的迷宫。别担心,我们不会一开始就让你啃硬骨头,而是从基础语法开始,让你慢慢品尝编程的美味。准备好了吗?让我们开始这场编程…...

Qt/C++路径轨迹回放/回放每个点信号/回放结束信号/拿到移动的坐标点经纬度
一、前言说明 在使用百度地图的路书功能中,并没有提供移动的信号以及移动结束的信号,但是很多时候都期望拿到移动的哪里了以及移动结束的信号,以便做出对应的处理,比如结束后需要触发一些对应的操作。经过搜索发现很多人都有这个…...

C 语言介绍及操作案例
C 语言是一种广泛使用的通用编程语言,具有高效、灵活和可移植性强等特点。 一、C 语言的基本特点 简洁高效 C 语言语法简洁,表达能力强。它提供了丰富的数据类型和运算符,可以方便地进行各种计算和操作。C 语言的代码执行效率高,能够直接访问硬件资源,适用于对性能要求较…...

Ivanti云服务被攻击事件深度解析:安全策略构建与未来反思
攻击事件背景 近期,威胁情报和研究机构Fortinet FortiGuard Labs发布了一份关于针对IT解决方案提供商Ivanti云服务设备(Ivanti Cloud Services Appliance,CSA)的复杂网络攻击的详细分析。 该攻击被怀疑是由国家级对手发起…...

如何做出正确选择编程语言:关于Delphi 与 C# 编程语言的优缺点对比
概述 为您的项目选择正确的技术可能是一项相当棘手的任务,尤其是当您以前从未需要做出这样的选择时。如今可用的选项范围非常广泛。虽然一些编程语言和工具有着相当悠久的历史,但其他一些则是刚刚开始赢得开发人员青睐的新手。 在这篇博文中࿰…...

39.3K Star,一个现代的数据库ORM工具,专为Node.js和TypeScript设计
大家好,今天给大家分享一个现代的数据库对象关系映射(Object-Relational Mapping,ORM)工具Prisma ORM,它旨在简化数据库操作,提高开发效率,并确保类型安全。 项目介绍 Prisma ORM适用于各种需要…...

Nginx和Mysql的基础命令
1.安装nginx brew install nginx 2.启动nginx brew services start nginx 3.查看nginx文件默认路径 brew info nginx 重装要先关闭nginx 4.nginx.conf 地址 nginx -t 5.nginx重启 brew services restart nginx 6.关闭nginx brew services stop nginx 7.卸载nginx brew uninstal…...