设计模式篇---代理模式
文章目录
- 概念
- 结构
- 实例
- 静态代理
- 动态代理
- 总结
概念
代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。
比如我们想从其他国家买东西,但我们无法直接联系外国的商家,可以找代理商,让他们帮我们处理,我们是客户端,只需要面向代理商即可,只需要把钱交给代理商,剩下的那些操作,比如联系商家、和商家签订协议等我们都不需要关心。
结构

Subject(抽象主题):它是代理类和真实类的共同接口,这样一来在任何使用真实对象的地方都可以使用代理对象,客户端通常需要针对抽象主题角色进行编程。
Proxy(代理类) :它包含了真实对象的引用,所以可以在任何时候操作真实对象。一般在调用真实对象前后还需要执行其他操作。
RealSubject(真实类–被代理类):真实类中实现了主要的业务操作。客户端可以调用代理类,来间接的调用真实类。
实例
静态代理
我们想从海外买台电脑,用代理模式实现这个流程。

购买东西的接口
public interface IBuySomething {void pay();
}
真实类,也就是被代理类
public class Person implements IBuySomething{@Overridepublic void pay() {System.out.println("付款");}
}
代理商,也就是代理类,他来帮我们联系商家
public class Agent implements IBuySomething {private IBuySomething person;public Agent(IBuySomething person) {this.person = person;}@Overridepublic void pay() {findBusiness();person.pay();}private void findBusiness() {System.out.println("我是代理商,付款之前先找到商家");}
}
客户端
public class Client {public static void main(String[] args) {IBuySomething person;person = new Agent(new Person());person.pay();}
}
打印结果:

也可以让代理商来替我们的朋友来买东西,只需要再声明一个朋友类,让代理商来代理即可。
朋友类
public class Friend implements IBuySomething{@Overridepublic void pay() {System.out.println("我是朋友,我付款");}
}
客户端
public class Client {public static void main(String[] args) {IBuySomething person;person = new Agent(new Friend());person.pay();}
}
打印结果

反过来,如果想换一家代理商,那就再创建一个新的代理商类即可。
public class Agent2 implements IBuySomething{private IBuySomething person;public Agent2(IBuySomething person) {this.person = person;}@Overridepublic void pay() {findBusiness();person.pay();}private void findBusiness() {System.out.println("我是另外一个代理商,付款之前先找到商家");}
}
动态代理
以上的这种代理方式叫做静态代理。
静态代理的特点是,一个代理类只能代理一个真实类,或者只能代理一个方法。因为它在执行前就编译成了class文件,不会进行改变了,所以被称为静态代理。
但如果我们想动态的代理不同的真实类,或者代理不同的方法,可以使用动态代理来实现。动态代理可以让系统在运行时根据实际需求来动态的创建代理类。
有关动态代理,有两个重要的类。
Proxy类
Proxy类提供了用于创建动态代理对象的方法。它的主要方法newProxyInstance
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
该方法即用来创建一个动态代理对象;第一个参数是代理类的类加载器(作用是将.class文件加载到jvm中,进而生成一个对象实例);第二个参数是真实类实现的接口列表;第三个是执行代理方法的具体程序—InvocationHandler。
简单总结下,要想生成一个代理对象,首先得创建class对象(第一个参数的作用),其次得知道代理谁(第二个参数的作用),最后代理的方法是什么(第三个参数)。这样看来,第二个和第三个参数都是动态的,可变的,这也就是代理模式的灵活性。
InvocationHandler
上面的第三个参数InvocationHandler 是一个接口,它只有一个invoke方法
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
该方法用来处理代理类实例的代理方法,并返回相应的结果。即我们代理的方法写在这个方法里。
第一个参数是代理对象;第二个参数是需要代理的方法;第三个参数是需要执行代理方法的参数。
还是拿买东西的例子来说,我们如果买完东西后,发现不合适,需要退款,这时候我们面向的还是代理商,但如果用静态代理的话,那还是需要再写一个代理退款的类,如果业务方法更多的话,那我们需要创建更多的静态代理类,这样处理起来很麻烦。如果用动态代理的话,就没有这么冗余。我们首先实现一个InvocationHandler,它的invoke方法是用来实现代理对象的方法。
public class AgentHandler implements java.lang.reflect.InvocationHandler {private Object object;public AgentHandler(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {findBusiness();Object result = method.invoke(object, args);return result;}private void findBusiness() {System.out.println("我是代理商,我要先找到商家");}
}
我们也增加一个退款的方法
public interface IBuySomething {void pay();void refund();
}
客户端调用
public class Client {public static void main(String[] args) {IBuySomething person = new Person();InvocationHandler handler = new AgentHandler(person);Object o = Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), handler);IBuySomething proxy = (IBuySomething) o;proxy.refund();}
}
打印结果:

总结
静态代理比较好理解,代理类里面实现了代理的方法。
而动态代理的代理对象是通过Proxy创建的,代理的方法是在InvocationHandler里的invoke方法里,和静态代理对比的话,代理类和代理方法是分离开的。
相关文章:
设计模式篇---代理模式
文章目录 概念结构实例静态代理动态代理 总结 概念 代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。 比如我们想从其他国家买东西,但我们无法直接联系外国的商家,可以找代理商,让他们…...
STM32单片机项目实例:基于TouchGFX的智能手表设计(2)UI交互逻辑的设计
STM32单片机项目实例:基于TouchGFX的智能手表设计(2)UI交互逻辑的设计 目录 一、UI交互逻辑的设计 1.1 硬件平台的资源 1.2 界面切换功能 1.3 表盘界面 1.4 运动界面 1.6 设置界面 1.7 应…...
ES-分析器
分析器 两种常用的英语分析器 1 测试工具 #可以通过这个来测试分析器 实际生产环境中我们肯定是配置在索引中来工作 GET _analyze {"text": "My Moms Son is an excellent teacher","analyzer": "english" }2 实际效果 比如我们有下…...
智能优化算法应用:基于缎蓝园丁鸟算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于缎蓝园丁鸟算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于缎蓝园丁鸟算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.缎蓝园丁鸟算法4.实验参数设定5.算法…...
【开发问题】vue的前端和java的后台,用sm4,实现前台加密,后台解密
sm4加密 vue引入的包代码加密解密 javamaven代码运行结果 vue 引入的包 npm install sm-crypto代码加密解密 加密: key :代表着密钥,必须是16 字节的十六进制密钥 password :加密前的密码 sm4Password :代表sm4加密…...
【算法专题】分治 - 快速排序
分治 - 快速排序 分治 - 快速排序1. 颜色分类2. 排序数组(快速排序)3. 数组中的第K个最大元素4. 库存管理Ⅲ5. 排序数组(归并排序)6. 交易逆序对的总数7. 计算右侧小于当前元素的个数8. 翻转对 分治 - 快速排序 1. 颜色分类 做题链接 -> Leetcode -75.颜色分类 题目&…...
UG NX二次开发(C#)-求曲线在某一点处的法矢和切矢
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、在UG NX中创建一个曲线3、直接放代码4、测试案例1、前言 最近确实有点忙了,好久没更新博客了。今天恰好有时间,就更新下,还请家人们见谅。 今天我们讲一下如何获取一条曲线上某一条曲…...
leetcode 622. 设计循环链表
这道题讲了两种方法,第一个代码是用数组实现的,第二个是用链表实现的,希望对你们有帮助 (最好在VS自己测试一遍,再放到 leetcode上哦) 下面的是主函数(作参考),静下心来…...
Linux:dockerfile编写搭建tomcat练习(9)
我使用的httpyum仓库 本地使用了5个文件,tomcat使用的官网解压直接用的包】 Dockerfile 主配置文件 基于centos基础镜像 jdk1.8.0_91 java环境 run.sh 启动脚本 centos.repo 仓库文件 tomcat 源码包 vim Dockerfile写入FROM centos MAINTAINER ta…...
Linux 基础IO
文章目录 前言基础IO定义系统IO接口文件描述符重定向原理缓冲区刷新 前言 要知道每个函数/接口的全部参数和返回值建议去官网或者直接在Linux的man手册中查,这不是复制粘贴函数用法的文章。 C语言文件读写介绍链接 基础IO定义 IO是Input/Output的缩写,…...
uniapp 打开文件管理器上传(H5、微信小程序、android app三端)文件
H5跟安卓APP 手机打开的效果图: Vue页面: <template><view class"content"><button click"uploadFiles">点击上传</button></view> </template><script>export default {data() {return…...
掌控安全 -- header注入
http header注入 该注入是指利用后端验证客户端口信息(比如常用的cookie验证)或者通过http header中获取客户端的一些信息(比如useragent用户代理等其他http header字段信息),因为这些信息是会重新返回拼接到后台中的&…...
windows批处理脚本(.bat)如何激活Anconda Prompt虚拟环境
通过call 来调用激活脚本, activate myenv指的是要激活的环境,若省略,则激活的是base环境。 call : 从另一个批处理程序调用一个批处理程序,而不停止父批处理程序。 call C:\ProgramData\Anaconda3\Scripts\activate.bat activate…...
扩散模型实战(十四):扩散模型生成音频
推荐阅读列表: 扩散模型实战(一):基本原理介绍 扩散模型实战(二):扩散模型的发展 扩散模型实战(三):扩散模型的应用 扩散模型实战(四ÿ…...
《微信小程序开发从入门到实战》学习四十七
4.4 云函数 4.4.5 云函数的定时触发 如果云函数需要定时执行,可以使用云函数定时触发器。配置了定时触发器,云函数会在相应时间点被自动触发。函数返回结果不会返回调用方 在需要添加触发器的云函数下新建文件config.json。格式如下: &quo…...
LeetCode刷题笔记之数组
一、二分查找 1. 704【二分查找】 题目: 给定一个 n 个元素 有序的(升序) 整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。代码:…...
ViT:视觉 Transformer
ViT:视觉 Transformer 网络结构Transformer 编码器MLP 头CNN 和 Transformer 网络结构 Transformer 的优势:注意力机制相当于一个多标签检索系统,位置嵌入能知道每个单词的位置,而且适合并行。 尝试把 Transformer 迁移到视觉领…...
Jmeter 请求签名api接口-BeanShell
Jmeter 请求签名api接口-BeanShell 项目签名说明编译扩展jar包jmeter 使用 BeanShell 调用jar包中的签名方法 项目签名说明 有签名算法的api接口本地不好测试,使用BeanShell 扩展jar 包对参数进行签名,接口签名算法使用 sha512Hex 算法。签名的说明如下…...
No suitable driver found for jdbc:mysql://localhost:3306(2023/12/7更新)
有两种情况: 压根没安装下载了但没设为库或方法不对 大多数为第一种情况: 一. 下载jdbc 打开网址选择一个版本进行下载 https://nowjava.com/jar/version/mysql/mysql-connector-java.html 二.安装jdbc 在项目里建一个lib文件夹 在把之前下载的jar文…...
word文档中数字格式转换(排版助手)
示例:李老师收入了234243.33元,产量3000公斤; 张老师收入了2324324元,产量45555公斤; 孙老师收入了600000元,产量2342公斤 王老师收入了1234443243元,产量1243142公斤。 1、数字批量转换成千…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
