当前位置: 首页 > 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 自身的强大报表…...

如何突破窗口限制:3分钟掌握WindowResizer强制调整技巧

如何突破窗口限制&#xff1a;3分钟掌握WindowResizer强制调整技巧 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 还在为那些无法拖拽大小的应用程序窗口而烦恼吗&#xff1f;Win…...

TinyTroupe:轻量级智能体协作范式与确定性AI工程实践

1. 项目概述&#xff1a;这不是另一个“小模型”&#xff0c;而是一套轻量级智能体协作范式你可能已经看过不少标题带“Tiny”“Mini”“Lite”的AI项目&#xff0c;它们大多是在说“把大模型压缩一下&#xff0c;跑在手机上”。但 Microsoft 的TinyTroupe完全不是这个路数——…...

NomNom终极指南:3个技巧让你轻松掌控《无人深空》存档

NomNom终极指南&#xff1a;3个技巧让你轻松掌控《无人深空》存档 【免费下载链接】NomNom NomNom is the most complete savegame editor for NMS but also shows additional information around the data youre about to change. You can also easily look up each item indi…...

SPT-AKI存档编辑器完全手册:单机版塔科夫终极存档修改指南

SPT-AKI存档编辑器完全手册&#xff1a;单机版塔科夫终极存档修改指南 【免费下载链接】SPT-AKI-Profile-Editor Программа для редактирования профиля игрока на сервере SPT-AKI 项目地址: https://gitcode.com/gh_mirro…...

Taotoken 官方价折扣与活动价助力个人开发者降低创新门槛

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken 官方价折扣与活动价助力个人开发者降低创新门槛 对于个人开发者和学生而言&#xff0c;探索大模型应用的最大挑战之一往往…...

别再只会用cv2.resize()了!手把手教你用Python复现最近邻和双线性插值(附完整代码)

从零实现图像缩放&#xff1a;深入理解最近邻与双线性插值的数学本质 当你在Jupyter Notebook里轻松敲下cv2.resize(img, (300,300))时&#xff0c;有没有想过这个看似简单的操作背后隐藏着怎样的数学魔法&#xff1f;今天我们将撕开OpenCV的封装外壳&#xff0c;用纯Python和N…...

企业组网实战:用爱快+水星AC打造跨地域无线网络,远程管理分支AP就这么简单

企业级无线组网实战&#xff1a;跨地域统一管理与远程控制方案 在数字化转型浪潮中&#xff0c;中小企业对无线网络的依赖程度越来越高。无论是总部办公室、分支机构还是临时办公点&#xff0c;稳定、安全且易于管理的无线网络已成为企业高效运营的基础设施。然而&#xff0c;…...

实测Taotoken平台API调用稳定性与延迟体感观察记录

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 实测Taotoken平台API调用稳定性与延迟体感观察记录 在将大模型能力集成到生产应用时&#xff0c;服务的稳定性和响应延迟是开发者关…...

如何免费获得Windows风扇智能控制:FanControl终极指南

如何免费获得Windows风扇智能控制&#xff1a;FanControl终极指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa…...

别再为毕设供电发愁了!手把手教你用航模电池+降压模块搞定多电压系统

毕设供电系统实战指南&#xff1a;航模电池与智能降压方案全解析 刚拿到毕设题目的电子系学生小张&#xff0c;正盯着实验室桌上散落的传感器、单片机和电机发愁——这些设备需要的供电电压各不相同&#xff1a;单片机要7-12V&#xff0c;电机要12V&#xff0c;传感器却只要5V。…...