什么是代理模式

代理模式(Proxy Pattern)是一种设计模式,它为对象提供一种代理或占位符,通过引入一个代理对象来控制对目标对象的访问。代理对象与目标对象具有相同的接口,客户端可以通过代理对象间接地与目标对象交互。代理模式的主要目的是为了在目标对象的操作前后添加额外的行为,或者为原本难以访问的对象提供访问途径,而不改变客户端代码的调用方式。

代理模式的基本角色如下:

  1. 目标对象(Target):定义了真实业务逻辑的对象,是代理对象所代表的真实对象。它可以是一个接口,也可以是一个具体的类。
  2. 代理对象(Proxy):持有目标对象的引用,提供与目标对象相同的接口。代理对象在执行目标对象方法时,可以添加额外的操作,如预处理、后处理、日志记录、权限检查、缓存、延迟加载等。
  3. 客户端(Client):通过代理对象来调用目标对象的方法。客户端并不关心是直接与目标对象交互还是与代理对象交互,因为它们具有相同的接口。

代理模式有两种常见的实现方式:

1. 静态代理

特点

  • 静态代理在编译期间就已经确定了代理类和目标类的关系,代理类是手动创建的,与目标类一一对应。
  • 静态代理通常用于为单一的目标对象提供代理。

示例

假设有一个Image接口和其实现类RealImage,现在我们创建一个静态代理类ProxyImage来为其提供缓存功能:

interface Image {void display();
}class RealImage implements Image {private String fileName;public RealImage(String fileName) {this.fileName = fileName;loadFromDisk(fileName); // 加载图片到内存}private void loadFromDisk(String fileName) {// 实际从磁盘加载图片的代码System.out.println("Loading image from disk: " + fileName);}@Overridepublic void display() {System.out.println("Displaying image: " + fileName);}
}class ProxyImage implements Image {private RealImage realImage;private String fileName;public ProxyImage(String fileName) {this.fileName = fileName;}@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(fileName);}realImage.display();}
}public class Client {public static void main(String[] args) {Image proxyImage = new ProxyImage("image.jpg");proxyImage.display(); // 第一次调用,从磁盘加载图片proxyImage.display(); // 第二次调用,直接从内存中显示图片}
}

在这个示例中,ProxyImage作为RealImage的静态代理,实现了相同的Image接口。在display()方法中,如果RealImage尚未创建,则先从磁盘加载图片,然后调用其display()方法。第二次调用时,由于图片已经加载到内存,直接调用RealImagedisplay()方法即可。

2. 动态代理

特点

  • 动态代理在运行时动态地创建代理对象,无需手动编写代理类。
  • 动态代理通常使用反射或字节码技术(如Java的java.lang.reflect.Proxy类或CGLIB库)来创建代理对象。
  • 动态代理可以为一组具有相同接口的目标对象提供代理,具有更好的通用性和灵活性。

示例(使用Java的java.lang.reflect.Proxy类):

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;interface Image {void display();
}class RealImage implements Image {// 同上...
}class ImageInvocationHandler implements InvocationHandler {private Image target;public ImageInvocationHandler(Image target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before displaying the image...");Object result = method.invoke(target, args);System.out.println("After displaying the image...");return result;}
}public class Client {public static void main(String[] args) {Image realImage = new RealImage("image.jpg");Image proxyImage = (Image) Proxy.newProxyInstance(Image.class.getClassLoader(),new Class[]{Image.class},new ImageInvocationHandler(realImage));proxyImage.display();}
}

在这个示例中,我们使用java.lang.reflect.Proxy类创建了一个动态代理对象proxyImage,它在调用display()方法时,会先执行ImageInvocationHandler中的invoke()方法,添加了显示图片前后的额外操作。ImageInvocationHandler持有RealImage对象的引用,并通过反射调用其display()方法。

总结来说,代理模式通过引入代理对象来控制对目标对象的访问,能够在不修改目标对象代码的前提下,为对象添加额外的行为或提供访问途径。静态代理和动态代理是代理模式的两种实现方式,各有优缺点,适用于不同的应用场景。

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

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

相关文章

【React】vite + react 项目,配置项目路径别名 @

vite react 项目,配置项目路径别名 1 安装 types/node2 在 vite.config.ts 中添加配置:3 配置路径别名的提示 使用 vite 开发 react 项目时,可以通过一下步骤配置路径别名: 1 安装 types/node npm i -D types/node2 在 vite.con…

LeetCode-560. 和为 K 的子数组【数组 哈希表 前缀和】

LeetCode-560. 和为 K 的子数组【数组 哈希表 前缀和】 题目描述:解题思路一:一边算前缀和一边统计。这里用哈希表统计前缀和出现的次数,那么和为k的子数组的个数就是当前前缀和-k的个数,即preSums[presum - k]。画个图表述就是&a…

无尘布擦拭过程中的问题及其解决方案

无尘布,作为一种广泛应用于电子、半导体、生物医药等领域的清洁材料,其质量和使用方式直接关系到产品生产的洁净度和质量。然而,在无尘布的擦拭过程中,常常会遇到一些问题,如接触不当的溶剂、胶水选择不当、产品收缩以…

内存管理--柔性数组

本次讲的是,柔性数组,如果哪位小博客想要了解的更多,可以登录下面这个网站,了解详细内容 C语言结构体里的成员数组和指针 | 酷 壳 - CoolShellhttps://coolshell.cn/articles/11377.html 我们就听说过数组,听说过柔性数…

游戏本笔记本更换@添加内存条实操示例@DDR5内存条

文章目录 添加内存条的意义准备工具设备拔出电源适配器并关机👺样机 内存条上的金手指安装过程Notes 安装后开机初次开机速度屏幕显示分辨率和闪烁问题检查安装后的效果 添加内存条的意义 参考双通道内存DDR5多通道内存-CSDN博客 准备工具 准备一个质量差不多的螺…

向量点乘有哪些作用呢

如下: 1.找到两个向量之间的夹角(不用多说) 2.求一个向量投影在另一个向量的投影: 我们把图中b的在a上的投影向量称作b1吧,因为b1就在a上,所以只需要求出b1的大小,然后乘以a的单位向量,我们就得到向量b1了…

Rust常用特型之Clone+Copy特型

Rust常用特型之CloneCopy特型。在Rust标准库中,存在很多常用的工具类特型,它们能帮助我们写出更具有Rust风格的代码。 今天,我们把Clone 和 Copy 特型放在一起学习。 (注:本文更多的是对《Programing Rust 2nd Editio…

类加载过程详解

1、加载 通过类的全名,获取类的二进制数据流。解析类的二进制数据流为方法区内的数据结构(Java类模型) 创建java.lang.Class类的实例,表示该类型。作为方法区这个类的各种数据的访问入口 2、验证 验证类是否符合JVM规范&…

Altair® Embed® 嵌入式系统的可视化环境

Altair Embed 嵌入式系统的可视化环境 Altair Embed 是一款成熟的工具,可从框图模型自动生成代码并将其传输到通用控制器硬件来开发嵌入式系统。 基于系统关系图创建工作仿真后,用户即可对硬件控制器自动生成相关代码,并通过硬件在环 (HIL)…

ubuntu 安装配置samba服务器完整教程

ubuntu 安装配置samba服务器完整教程 问题描述解决方法郑重声明:本人原创博文,都是实战,均经过实际项目验证出货的 转载请标明出处:攻城狮2015 Platform: Intel arm64 OS:ubuntu16.04 问题描述 在安卓驱动系统开发的过程中,会需要打架服务器,又需要搭建samba服务器,下面就…

【BlossomConfig】SpringCloud项目是如何对bootstrap配置文件进行加载的?

文章目录 bootstrap配置文件的读取 网关项目源码 RPC项目源码 配置中心项目源码 bootstrap配置文件的读取 我们首先来了解一下springboot是如何做配置管理的。 了解了springboot对配置文件的管理,我们就能知道为什么springcloud类型的项目要使用bootstrap配置文件了…

美国RAKsmart:裸机云站群服务器配置详解

裸机云,也称为物理云,是一种云服务模式,它为用户提供了接近物理机性能的云服务器。而站群服务器,则是为了支持多个网站或应用程序的运行而设计的服务器。美国RAKsmart作为一家知名的云服务提供商,其裸机云站群服务器配…

【大模型】大模型发展历程,从GPT开始到Grok-1.5霸榜

目录 大模型发展历程 大模型发展历程 2018年6月,openAI发布GPT1;2019年2月,发布GPT2;2020年6月,发布GPT-3。 2022年11月30日,openAI发布ChatGPT。 2023年3月14日,GPT-4 发布。 2023年7月18日…

Proteus 12V to 5V buck电路仿真练习及遇到的一些问题汇总

基础电路仿真实验记录贴!!!如有写的不对的地方欢迎交流指正!!! 平台:PC win10 软件:Proteus8.10 仿真目标:buck降压电路(PWM控制输出电压) 写在…

八皇后问题解决过程字符串可视化

查找到问题,暂停600毫秒, 穷举本行,200毫秒 返回上一层之前,会弹出回滚上一层(4,X),并暂停600毫秒 成功返回时,会弹出上一层具体数据如(4,3&a…

Java | Leetcode Java题解之第3题无重复字符的最长子串

题目&#xff1a; 题解&#xff1a; class Solution {public int lengthOfLongestSubstring(String s) {// 哈希集合&#xff0c;记录每个字符是否出现过Set<Character> occ new HashSet<Character>();int n s.length();// 右指针&#xff0c;初始值为 -1&#…

分治——归并排序算法

例题一 解法&#xff08;归并排序&#xff09;&#xff1a; 算法思路&#xff1a; 归并排序的流程充分的体现了「分⽽治之」的思想&#xff0c;⼤体过程分为两步&#xff1a; ◦ 分&#xff1a;将数组⼀分为⼆为两部分&#xff0c;⼀直分解到数组的⻓度为 1 &#xff0c;使…

【MySQL】DQL-分组查询-语法&where与having的区别&注意事项&可cv例题语句

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

【Web应用技术基础】CSS(6)——使用 HTML/CSS 实现 Educoder 顶部导航栏

第一题&#xff1a;使用flex布局实现Educoder顶部导航栏容器布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Educoder</title><script src"https://cdn.staticfile.org/jquery/1.1…

EDM营销文案的撰写技巧?如何提升转化率?

EDM营销文案与SEO策略如何结合&#xff1f;怎么写有效营销邮件&#xff1f; EDM仍然是一种高效且经济的推广手段。撰写优质的EDM营销文案&#xff0c;不仅可以提升品牌形象&#xff0c;还能有效促进销售转化。那么&#xff0c;如何撰写出引人入胜的EDM营销文案呢&#xff1f;A…