设计模式之代理模式(Proxy Pattern)【结构性模式】

在这里插入图片描述

为什么用结构性模式?

  • 结构性模式关注点“怎样组合对象/类?”所以我们关注下类的组合关系
  • 类结构型模式关心类的组合,由多个类可以组合成一个更大的(继承)
  • 对象结构型模式关心类与对象的组合,通过关联关系在一个类中定义另一个类的实例对象(组合)
  • 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式
  1. 适配器模式(Adapter Pattern):两个不兼容接口之间适配的桥梁。
  2. 桥接模式(Bridge Pattern):相同功能抽象化与实现化解耦,抽象与实现可以独立升级。
  3. 过滤器模式(Filter、Criteria Pattern):使用不同的标准来过滤一组对象。
  4. 组合模式(Composite Pattern):相似对象进行组合,形成树形结构。
  5. 装饰器模式(Decorator Pattern):向一个现有的对象添加新的功能,同时又不改变其结构。
  6. 外观模式(Facade Pattern):向现有的系统添加一个接口,客户端访问此接口来隐藏系统的复杂性。
  7. 享元模式(Flyweight Pattern):尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
  8. 代理模式(Proxy Pattren):一个类代表另一个类的功能。

🍭结构性模式之代理模式(Proxy Pattern)

🍎代理模式

  • 代理模式(Proxy Pattern),给某一个对象提供一个代理,并由代理对象控制原对象的引用,对象结构型模式。这种也是静态代理。

在这里插入图片描述

代理模式包含如下角色:

  • Subject:抽象主体角色(抽象类或接口)
  • Proxy:代理主体角色(代理对象类)
  • RealSubject:真实主体角色(被代理对象类)

代理模式分为:

  • 静态代理
  • JDK动态代理
  • Cglib动态代理
🍔静态代理代码实现
/*** 抽象主体。被代理角色能干什么*/
public interface ManTikTok {void tikTok();
}
/*** Subject:主体*/
public class ZhuicatTikTok implements ManTikTok {@Overridepublic void tikTok() {System.out.println("张三 tiktok");}
}
/*** 代理一般都是和被代理对象属于同一个接口*/
public class TikTokProxy implements ManTikTok {private ManTikTok manTikTok; // 被代理对象public TikTokProxy(ManTikTok manTikTok) {this.manTikTok = manTikTok;}@Overridepublic void tikTok() {// 增强功能System.out.println("渲染直播间");manTikTok.tikTok();}
}
public class MainTest {public static void main(String[] args) {ManTikTok manTikTok = new ZhuicatTikTok();TikTokProxy tikTokProxy = new TikTokProxy(manTikTok);tikTokProxy.tikTok();}
}
渲染直播间
张三 tiktok

可以发现:静态代理就是装饰器,我们可以认为装饰器模式是代理模式的一种

使用静态代理时,每一次代理的代理对象不一样,就需要创建不同的代理类。

🍔JDK动态代理代码实现
/*** 抽象主体。被代理角色能干什么*/
public interface ManTikTok {void tikTok();
}
public interface SellTikTok {Integer sell();
}
/*** Subject:主体*/
public class ZhuicatTikTok implements ManTikTok,SellTikTok {@Overridepublic void tikTok() {System.out.println("张三 tiktok");}@Overridepublic Integer sell() {System.out.println("只要666");return 666;}public void haha() {System.out.println("哈哈");}
}
public class JdkTikTokProxy<T> implements InvocationHandler {private T target;public JdkTikTokProxy(T target) {this.target = target;}/*** ClassLoader loader:当前被代理对象的类加载器* Class<?>[] interfaces:当前被代理对象所实现的所有接口* InvocationHandler h:被代理对象再执行目标方法时我们使用h可以定义拦截增强方法*/// 获取被代理对象的代理对象public static <T> T getProxy(T t) {Object o = Proxy.newProxyInstance(t.getClass().getClassLoader(),t.getClass().getInterfaces(),new JdkTikTokProxy(t));return (T) o;}/*** 定义目标方法的拦截逻辑:每个方法都会进来的*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 反射执行System.out.println("真正执行被代理对象的方法");Object invoke = method.invoke(target, args);System.out.println("返回值为:" + invoke);return invoke;}
}
/*** 动态代理模式* 代理对象和目标对象的相同点时需要实现同一个接口*/
public class MainTest {public static void main(String[] args) {ZhuicatTikTok tikTok = new ZhuicatTikTok();// new CatManTikTok proxy = JdkTikTokProxy.getProxy(tikTok);
//        proxy.tikTok();
//        proxy.hashCode();((SellTikTok) proxy).sell();// 能不能代理被代理对象奔雷自己的方法?不能,proxy只能转为接口类型
//        ((ZhuicatTikTok) proxy).haha();System.out.println(Arrays.asList(proxy.getClass().getInterfaces()));}
}
真正执行被代理对象的方法
只要666
返回值为:666
[interface com.xl.web.proxy.synamic.ManTikTok, interface com.xl.web.proxy.synamic.SellTikTok]

缺点:被代理对象必须实现接口才行

🍔Cglib动态代理代码实现

引入依赖:

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
public class ZhuicatTikTok  {public void tikTok() {System.out.println("张三 tiktok 哈哈哈哈哈");}}
/*** 使用 cglib 帮我们创建出代理对象*/
public class CglibProxy {// 为任意对象创建代理public static <T> T createProxy(T t) {// 1、创建一个增强器Enhancer enhancer = new Enhancer();// 2、设置要增强哪个类的功能。增强类为t类动态创建一个子类enhancer.setSuperclass(t.getClass());// 3、设置回调enhancer.setCallback(new MethodInterceptor() {/*** 拦截并处理被代理对象的方法调用* @param o 被代理对象* @param method 将要执行的目标方法* @param args 目标方法的参数数组* @param methodProxy 方法代理对象,用于调用目标方法* @return 返回经过拦截处理后的方法结果* @throws Throwable 若方法调用过程中出现异常,则抛出*/@Overridepublic Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {// 在调用实际方法前的操作,例如记录日志、权限校验等System.out.println("拦截钱");// 通过methodProxy调用原始方法,并获取返回值// Object result = methodProxy.invokeSuper(o, args);// 或【本质就是执行 目标对象的 方法】Object result = method.invoke(t, args);// 在调用实际方法后的操作,例如更新数据状态、发送通知等System.out.println("拦截后");// 返回处理后的结果return result;}});return (T) enhancer.create();}
}
public class MainTest {public static void main(String[] args) {ZhuicatTikTok zhuicatTikTok = new ZhuicatTikTok();ZhuicatTikTok proxy = CglibProxy.createProxy(zhuicatTikTok);proxy.tikTok();System.out.println("========");proxy.hashCode();}
}
拦截钱
张三 tiktok 哈哈哈哈哈
拦截后
========
拦截钱
拦截后

原本的类

cglib代理类 继承了 原本的类

🍕应用场景

  • 什么场景用到?
    • Mybatis 的 mapper 到底是什么?怎么生成的?
      • Mybatis 采用的是 JDK 动态代理
      • UserMapper,Mybatis 帮我们写实现 MapperProxy
    • Seata 的 DataSourceProxy 是什么?
    • DruidDataSource 存在的 Proxy 模式

区别装饰器和代理模式

  • 装饰器和代理之间的区别很细微,可以认为装饰器是代理的一个子集。
  • 静态代理就是装饰器的方式。

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

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

相关文章

第十五届蓝桥杯模拟考试III_物联网设计与开发官方代码分析

目录 前言&#xff1a;显示界面部分&#xff1a; 前言&#xff1a; 这次模拟的效果很不好。85分&#xff0c;4h的限时我花了两天完成&#xff0c;这个时间是远远超出要求的&#xff0c;而且最后还只拿到56分&#xff0c;抛开分数高低不提&#xff0c;就这个用时属实蜗牛一样的速…

【matlab】exportgraphics函数将生成的图片保存到指定文件夹中

【matlab】exportgraphics函数将生成的图片保存到指定文件夹中 使用matlab中&#xff0c;很多时候我们会生成一些图片&#xff0c;并且我们希望生成完显示出来后自动保存到指定路径&#xff0c;以下是本人常用的一个方法推荐 在Matlab中&#xff0c;exportgraphics函数用于将…

Seata 2.x 系列【8】Spring Cloud 集成客户端

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Seata 版本 2.0.0 本系列Spring Boot 版本 3.2.0 本系列Spring Cloud 版本 2023.0.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-seata-demo 文章目录 1. 前言2. 问题演…

裸辞18K外包,面试阿里、字节全都一面挂,哭死.....

测试员可以先在外包积累经验&#xff0c;以后去大厂就很容易&#xff0c;基本不会被卡&#xff0c;事实果真如此吗&#xff1f;但是在我身上却是给了我很大一巴掌... 所谓今年今天履历只是不卡简历而已&#xff0c;如果面试答得稀烂&#xff0c;人家根本不会要你。况且要不是大…

iptables详细介绍

在 CentOS 中,iptables 是一种用于配置和管理网络防火墙的工具,它提供了一种灵活和强大的方式来控制进出服务器的网络流量。以下是 CentOS 中 iptables 的主要内容: 规则链(Chains): iptables 使用规则链来组织规则,常见的链包括: INPUT:处理进入服务器的数据包。OUTP…

固定资产管理系统:井然有序,提升利用率,降损增值的解决之道。

固定资产管理系统是一种用于管理和跟踪组织内固定资产的软件系统。固定资产是指组织长期持有并用于生产、运营或提供服务的资产&#xff0c;例如土地、建筑物、机器设备、车辆等。 固定资产管理系统提供了一种集中管理和监控固定资产的方式&#xff0c;帮助组织更好地管理其资产…

外包干了9天,技术退步明显。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;2018年我通过校招踏入了南京一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

HarmonyOS NEXT应用开发—自定义日历选择器

介绍 本示例介绍通过CustomDialogController类显示自定义日历选择器。 效果图预览 使用说明 加载完成后显示主界面&#xff0c;点当前日期后会弹出日历选择器&#xff0c;选择日期后会关闭弹窗&#xff0c;主页面日期会变成选定的日期。 实现思路 获取当前月和下个月的日期…

技术资讯:Volar正式更名为Vue-Official

大家好&#xff0c;我是大澈&#xff01; 本文约700字&#xff0c;整篇阅读大约需要1分钟。 关注微信公众号&#xff1a;“程序员大澈”&#xff0c;免费加入问答群&#xff0c;一起交流技术难题与未来&#xff01; 现在关注公众号&#xff0c;免费送你 ”前后端入行大礼包“…

【智能算法】人工水母搜索算法(JS)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.代码实现4.参考文献 1.背景 2020年&#xff0c;Chou 等人受到水母运动行为启发&#xff0c;提出了人工水母搜索算法(Artificial Jellyfish Search Optimizer, JS)。 2.算法原理 2.1算法思想 JS模拟了水母的搜索行为&#xf…

Halcon文件操作

1、Region读写操作 region&#xff08;区域&#xff09;是一种重要的数据类型&#xff0c;用于表示图像中的特定区域。这些区域可以代表图像中的目标、感兴趣的区域、边缘、形状等等 read_image (Image, printer_chip/printer_chip_01) dev_open_window (0, 0, 512, 512, black…

mysql: 如何开启慢查询日志?

1 确认慢查询日志功能已开启 执行以下sql语句&#xff0c;查看慢查询功能是否开启&#xff1a; show VARIABLES like slow_query_log;如果为ON&#xff0c;表示打开&#xff1b;如果为OFF&#xff0c;表示没有打开&#xff0c;需要开启慢查询功能。 执行以下sql语句&#xff0…