当前位置: 首页 > news >正文

【设计模式】之代理模式(两种)

系列文章目录

(其他设计模式可以参考 👉👉👉)设计模式_小杰不秃头的博客  😊😄😛


前言

今天继续给大家介绍23种设计模式中的代理模式,熟悉Spring的小伙伴都知道,Aop使用的就是代理模式,所以,代理模式还是非常重要的,在工作中用的也是非常的多。🌈


一、代理模式

代理模式(Proxy Pattern)面向对象编程中的一种设计模式,它为其他对象提供一个代理占位符,以控制对这个对象的访问。代理对象在客户端目标对象之间起到中介的作用,客户端并不直接与目标对象交互,而是通过代理对象来间接调用目标对象的方法。(简单理解就是“房子中介”的一个角色)

特点

  1. 中介作用:代理对象作为客户端和目标对象之间的中介,可以拦截或修改客户端对目标对象的请求。
  2. 功能增强:可以在不修改目标对象代码的前提下,通过代理对象为目标对象增加额外的功能。如:Spring中的AOP
  3. 控制访问:代理对象可以控制对目标对象的访问,比如检查权限、记录日志、实现延迟加载等。

举一个简单的例子帮助大家理解,假如说你想买一个房子,但是你没有时间去挑选,所以你就找了一个房子中介帮你去找房子,这个过程就是一个代理的过程,房子中介就是一个代理对象。

二、静态代理

1、静态代理定义和特点

静态代理(Static Proxy):是在程序编译时确定代理类的代码,代理类和目标类实现了相同的接口。静态代理的实现相对简单,代理对象和目标对象实现相同的接口,客户端通过代理对象调用目标对象的方法。

特点:静态代理需要手动编写代理类的代码,因此当接口发生变化时,代理类也需要相应地修改。由于代理类在编译期间就已经确定,因此性能相对较高。但是,静态代理只能为给定接口的实现类做代理,如果接口不同则需要重新定义不同的代理类。

2、使用场景

使用场景:静态代理通常用于为一些功能较为简单的类提供代理,如增加日志记录、性能监控等功能。由于静态代理需要手动编写代理类的代码,因此它通常适用于接口稳定、功能较为简单的场景。

3、静态代理的简单实现

这里举一个比较粗糙的例子,模拟插入订单的这个业务场景。

跟我们平时开发的一样,首先创建实体类Order

public class Order {private String info;private String userId;public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}@Overridepublic String toString() {return "Order{" +"info='" + info + '\'' +", userId='" + userId + '\'' +'}';}
}

创建持久层的接口和实现类

public interface OrderDao {int insertOrder(Order order);
}public class OrderDaoImpl implements OrderDao {@Overridepublic int insertOrder(Order order) {System.out.println("持久层...插入订单..."+order.toString());return 1;}
}

创建服务层的接口和实现类

public interface OrderService {int insertOrder(Order order);
}public class OrderServiceImpl implements OrderService {private OrderDao orderDao;@Overridepublic int insertOrder(Order order) {orderDao = new OrderDaoImpl();System.out.println("业务层...调用持久层insertOrder方法...");return orderDao.insertOrder(order);}
}

关键一步,创建静态代理对象

public class OrderServiceImplStaticProxy {private OrderService orderService;public int insertOrder(Order order){before();orderService = new OrderServiceImpl();int result = orderService.insertOrder(order);after();return result;}private void after() {System.out.println("静态代理对象...提交事务...");}private void before() {System.out.println("静态代理对象...开启事务...");}
}

测试

public class Test {public static void main(String[] args) {Order order = new Order();order.setInfo("xxxx笔记本电脑");order.setUserId("1");OrderServiceImplStaticProxy proxy = new OrderServiceImplStaticProxy();proxy.insertOrder(order);}
}/*打印结果:
静态代理对象...开启事务...
业务层...调用持久层insertOrder方法...
持久层...插入订单...Order{info='xxxx笔记本电脑', userId='1'}
静态代理对象...提交事务...
*/

三、动态代理

1、动态代理定义和特点

 动态代理(Dynamic Proxy)是在程序运行过程中通过反射机制动态生成代理类的代码,实现对目标类的代理访问。动态代理可以代理任意实现了接口的类,不受接口的限制。

特点:动态代理可以根据具体需求动态生成代理类,避免了手动编写代理类的繁琐工作,方便接口的扩展和修改。由于动态代理在程序运行时生成代理类的代码,因此性能较静态代理略低。但是,动态代理的灵活性 更高,可以代理任意实现了接口的类。

2、使用场景

使用场景动态代理广泛应用于各种场景,包括但不限于AOP(面向切面编程)、远程方法调用、RPC(远程 过程调用)等。通过动态代理,我们可以实现对目标方法的拦截和增强,将系统的横切关注点(如日志记录、性能统计等)与业务逻辑代码进行解耦,提高代码的可维护性和可扩展性。

3、动态代理的简单实现

这里例子还以插入订单为例,其他都不变,只需将静态代理换为动态代理就可。

public class OrderServiceImplDynamicProxy implements InvocationHandler {private Object orderService;public OrderServiceImplDynamicProxy(Object service){this.orderService = service;}public Object bind(){//创建动态代理对象return Proxy.newProxyInstance(orderService.getClass().getClassLoader(), orderService.getClass().getInterfaces(),this);}private void after() {System.out.println("动态代理对象...提交事务...");}private void before() {System.out.println("动态代理对象...开启事务...");}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();Object o = method.invoke(orderService, args);after();return o;}
}

测试

public class Test {public static void main(String[] args) {OrderService service = (OrderService)new OrderServiceImplDynamicProxy(new OrderServiceImpl()).bind();Order order = new Order();order.setInfo("xxx手机");order.setUserId("2");service.insertOrder(order);}
}/*打印结果:
动态代理对象...开启事务...
业务层...调用持久层insertOrder方法...
持久层...插入订单...Order{info='xxx手机', userId='2'}
动态代理对象...提交事务...
*/


总结

总结来说,静态代理和动态代理各有优缺点,适用于不同的场景。静态代理适用于接口稳定、功能较为简单的场景,而动态代理则适用于需要灵活代理任意实现了接口的类的场景。

相关文章:

【设计模式】之代理模式(两种)

系列文章目录 (其他设计模式可以参考 👉👉👉)设计模式_小杰不秃头的博客 😊😄😛 前言 今天继续给大家介绍23种设计模式中的代理模式,熟悉Spring的小伙伴都知道&#xf…...

【工具篇】-什么是.NET

“.NET":.NET Core是由Microsoft开发,目前在.NET Foundation(一个非营利的开源组织)下进行管理。.NET Core是用C#和C编写的,并采用MIT协议作为开源协议。 简单来说:就是开发框架。 .NET 又称 .NET 平台或 .NET 框架&#xf…...

OmniReader Pro mac激活版:智慧阅读新选择,开启高效学习之旅

在追求知识的道路上,一款优秀的阅读工具是不可或缺的。OmniReader Pro作为智慧阅读的新选择,以其独特的功能和卓越的性能,为您开启高效学习之旅。 OmniReader Pro具备高效的文本识别和处理技术,能够快速准确地提取文档中的关键信息…...

Stable Diffusion学习记录

文章目录 前言电脑配置推荐环境搭建下载地址安装步骤步骤一,打开下载的秋叶整合包,路径秋叶整合包/sd-wenui-aki步骤二,打开下载好的sd-webui-aki-v4.8.7解压包 Stable Diffusion软件配置,插件安装,模型下载Stable Dif…...

安装openssh-server,提供远程ssh

安装openssh-server,提供远程ssh 1.检查自己是否安装了openssh-server dpkg -l | grep ssh如果输出内容有openssh-server,说明已经安装过了,可以跳过下一步 2.安装openssh-server 由于ubuntu自带ssh客户端,只需要安装openssh-se…...

华纳云:选择数据库服务器你需要注意的5个原则

选择数据库服务器时,有几个关键原则需要注意,以确保选择的服务器能够满足你的需求并提供可靠的性能和安全性。 1. 性能需求 考虑你的应用程序对性能的需求,包括处理能力、内存、存储和网络带宽等方面。根据应用程序的负载和预期的并发访问量&…...

Linux动态库与静态库解析

文章目录 一、引言二、C/C源文件的编译过程三、静态库1、静态库的定义和原理2、静态库的优缺点3、静态库的创建和使用a、创建静态库b、使用静态库 四、动态库1、动态库的定义和原理2、动态库的优缺点3、动态库的创建和使用示例a、创建动态库b、使用动态库 五、动静态库的比较 一…...

后端的一些科普文章

后端开发一般有4个方面 后端开发流程 1阶段 域名认证 是每一个计算机在网络上有一个ip地址,可以通过这个地址来访问102.305.122.5(举例), 但是这个公网ip地址,比较难记忆,所以大家使用域名来更好的记忆…...

【Android学习】日期和时间选择对话框

实现功能 实现日期和时间选择的对话框&#xff0c;具体效果可看下图(以日期为例) 具体代码 1 日期对话框 1.1 xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android&quo…...

在Linux上使用Selenium驱动Chrome浏览器无头模式

大家好&#xff0c;我们平时在做UI自动化测试的时候&#xff0c;经常会用到Chrome浏览器的无头模式&#xff08;无界面模式&#xff09;&#xff0c;并且将测试代码部署到Linux系统中执行&#xff0c;或者平时我们写个爬虫爬取网站的数据也会使用到&#xff0c;接下来和大家分享…...

Feign 第一次调用为什么会很慢?

feign调用的大致过程&#xff1f; Feign进行远程调用的&#xff0c;这里面包括&#xff0c;注册中心、负载均衡、FeignClient之间的关系&#xff0c;微服务通过不论是eureka、nacos也好注册到服务端&#xff0c;Feign是靠Ribbon做负载的&#xff0c;而Ribbon需要拿到注册中心的…...

Spring Framework-简介

Spring Framework Java Spring是一个开源的Java应用框架&#xff0c;它的主要目的是简化企业级应用开发的复杂性。Spring框架为开发者提供了许多基础功能&#xff0c;使得开发者能够更专注于业务逻辑的实现&#xff0c;而不是底层的细节。 主要特点和功能&#xff1a; 控制反…...

Linux——PHP8.0编译安装和yum安装

文章目录 Linux——PHP8.0编译安装和yum安装PHP8.0编译安装PHP8.0yum安装 Linux——PHP8.0编译安装和yum安装 PHP8.0编译安装 此内容参考于&#xff1a;https://www.cnblogs.com/jhno1/p/14237034.html 安装依赖 # 安装编译依赖 [rootcsq ~]# yum -y install ncurses ncurses…...

【通义千问系列】Qwen-Agent 从入门到精通【持续更新中……】

目录 前言一、快速开始1-1、介绍1-2、安装1-3、开发你自己的Agent 二、Qwen-Agent的使用和开发过程2-1、Agent2-1-1、Agent使用2-1-2、Agent开发 2-2、Tool2-2-1、工具使用2-2-2、工具开发 2-3、LLM2-3-1、LLM使用2-3-2、LLM开发 三、基于Qwen-Agent的案例分析3-1、3-2、 总结 …...

1081:分苹果

1081&#xff1a;分苹果 时间限制: 1000 ms 内存限制: 65536 KB 提交数:65448 通过数: 54401 【题目描述】 把一堆苹果分给n个小朋友&#xff0c;要使每个人都能拿到苹果&#xff0c;而且每个人拿到的苹果数都不同的话&#xff0c;这堆苹果至少应该有多少个&#x…...

Linux—-vim基础使用

1、基本概念 Vim的工作模式有四种&#xff0c;普通模式&#xff0c;输入模式&#xff0c;命令模式&#xff0c;可视模式。 在终端中打开vim&#xff0c;只需要输入vim 文件&#xff0c;在普通模式下按i就会进入到输入模式&#xff0c;按下:进入命令模式&#xff0c;输入:q就可…...

《ESP8266通信指南》12-Lua 固件烧录

往期 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP8266通信指南》10-MQTT通信&#xff08;Arduino开发&#xff09;-CSDN博客 《ESP8266通信指南》9-TCP通信&#xff08;Arudino开发&#xff09;-CSDN博客 《ESP8266通信指南》8-连接WIFI&#xff08;Arduino开发…...

Covalent Network(CQT)通过 “新曙光” 计划实现重要里程碑,增强以太坊时光机,提供 30% 的年化质押收益率

Covalent Network&#xff08;CQT&#xff09;作为集成超过 280 条区块链&#xff0c;并服务于超过 2.8 亿个钱包的领先结构化数据基础设施层&#xff0c;宣布了其战略计划 “新曙光” 中的一个重要进展。随着网络升级并完成了准备工作的 75%&#xff0c;这将为即将部署的以太坊…...

JVM8参数设置相关

1、堆内存设置 JVM堆内存的设置大小应根据应用程序的具体需求和系统环境来确定。以下是一些常见的考虑因素和建议&#xff1a; 应用程序需求&#xff1a;如果应用程序需要处理大量数据或运行多个线程&#xff0c;那么可能需要更大的堆内存。反之&#xff0c;如果应用程序的需…...

送别PI-DataLink,行列视(RCV)完美替代

行列视&#xff08;RCV&#xff09;和 OSI PI 实时数据库自带的 PI-DataLink 报表工具&#xff0c;属于以实时数 据库为主要数据源的报表产品。 PI-DataLink 是专门针对 PI 实时数据库系统开发的一套 Excel 报表插件&#xff0c;功能强大&#xff0c;借助 Excel 自身的强大报表…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...