Java设计模式-代理模式

news/2024/11/27 2:10:03/

简介

代理模式是一种结构型设计模式,它可以让我们通过一个代理对象来访问一个真实的目标对象,从而实现对目标对象的功能扩展或保护。代理模式的主要角色有三个:

  • 抽象主题(Subject):定义了真实主题和代理主题的公共接口,使得在任何使用真实主题的地方都可以使用代理主题。
  • 真实主题(RealSubject):实现了抽象主题的接口,定义了真实的业务逻辑,是代理主题所代表的真实对象。
  • 代理主题(Proxy):也实现了抽象主题的接口,但是在调用真实主题的方法之前或之后,可以执行一些额外的操作,从而对真实主题进行控制或增强。

代理模式可以帮助我们解决以下几种问题:

  • 当我们无法或不想直接访问一个对象时,可以通过一个代理对象来间接访问,例如远程代理、虚拟代理等。
  • 当我们想要给一个对象提供额外的功能时,可以通过一个代理对象来实现,而不需要修改原有的对象,例如缓存代理、日志代理等。
  • 当我们想要给一个对象增加一些访问控制或安全保护时,可以通过一个代理对象来实现,例如防火墙代理、权限代理等。

实现

根据代理模式的定义,我们可以用以下的类图来表示它的结构:

image-20230505112244447

其中,Client是客户端类,它需要使用Subject接口提供的方法。Proxy是代理类,它持有一个RealSubject的引用,并且实现了Subject接口。RealSubject是真实类,它也实现了Subject接口,并且定义了具体的业务逻辑。

代理模式有多种类型,例如静态代理、动态代理等,代理模式也有自己的优缺点,使用时需要根据具体的场景和需求来选择合适的类型和方式。

静态代理实现

下面我们用Java代码来实现一个静态代理的例子:

// 抽象主题接口
public interface Subject {// 定义一个抽象方法void request();
}// 真实主题类
public class RealSubject implements Subject {// 实现抽象方法@Overridepublic void request() {// 真实的业务逻辑System.out.println("RealSubject is doing something...");}
}// 代理主题类
public class Proxy implements Subject {// 持有一个真实主题的引用private RealSubject realSubject;// 构造方法,传入一个真实主题对象public Proxy(RealSubject realSubject) {this.realSubject = realSubject;}// 实现抽象方法@Overridepublic void request() {// 在调用真实主题之前,可以执行一些额外操作System.out.println("Proxy is doing something before...");// 调用真实主题的方法realSubject.request();// 在调用真实主题之后,可以执行一些额外操作System.out.println("Proxy is doing something after...");}
}// 客户端类
public class Client {public static void main(String[] args) {// 创建一个真实主题对象RealSubject realSubject = new RealSubject();// 创建一个代理对象,并传入真实主题对象Proxy proxy = new Proxy(realSubject);// 使用代理对象来调用抽象方法proxy.request();}
}
运行结果如下:
Proxy is doing something before...
RealSubject is doing something...
Proxy is doing something after...

从运行结果可以看出,代理对象在调用真实对象的方法之前和之后,都执行了一些额外的操作,从而对真实对象进行了增强或控制。

动态代理实现

动态代理是一种特殊的代理模式,它可以在运行时动态地创建代理对象,而不需要事先定义代理类。动态代理可以更灵活地适应不同的场景和需求,但是也更复杂和难以理解。

这个例子是使用JDK动态代理来实现一个日志代理,它可以在调用目标对象的方法之前和之后,记录相关的日志信息。代码如下:

// 抽象主题接口
public interface Subject {// 定义一个抽象方法void request();
}// 真实主题类
public class RealSubject implements Subject {// 实现抽象方法@Overridepublic void request() {// 真实的业务逻辑System.out.println("RealSubject is doing something...");}
}// 日志处理器类,实现了InvocationHandler接口,用于定义代理逻辑
public class LogHandler implements InvocationHandler {// 持有一个目标对象的引用private Object target;// 构造方法,传入一个目标对象public LogHandler(Object target) {this.target = target;}// 实现invoke方法,用于调用目标对象的方法,并在之前和之后执行日志操作@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在调用目标对象之前,记录开始时间long startTime = System.currentTimeMillis();System.out.println("开始执行" + method.getName() + "方法...");// 调用目标对象的方法,并获取返回值Object result = method.invoke(target, args);// 在调用目标对象之后,记录结束时间和耗时long endTime = System.currentTimeMillis();long duration = endTime - startTime;System.out.println("结束执行" + method.getName() + "方法,耗时" + duration + "毫秒");// 返回结果return result;}
}// 客户端类
public class Client {public static void main(String[] args) {// 创建一个真实主题对象RealSubject realSubject = new RealSubject();// 创建一个日志处理器对象,并传入真实主题对象LogHandler logHandler = new LogHandler(realSubject);// 使用Proxy类的静态方法newProxyInstance来动态地创建一个代理对象,传入真实主题对象的类加载器、接口和处理器Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), logHandler);// 使用代理对象来调用抽象方法proxy.request();}
}

运行结果如下:

开始执行request方法...
RealSubject is doing something...
结束执行request方法,耗时1毫秒

从运行结果可以看出,代理对象在调用真实对象的方法之前和之后,都执行了一些日志操作,从而对真实对象进行了增强。

优缺点

静态代理模式

优点:

  • 代理模式可以实现对真实对象的功能扩展或保护,而不需要修改原有的对象,符合开闭原则。
  • 代理模式可以实现对真实对象的访问控制或延迟加载,提高系统的性能和安全性。
  • 代理模式可以实现对真实对象的透明访问,客户端只需要使用抽象主题的接口,而不需要关心真实对象和代理对象的细节。

缺点:

  • 代理模式会增加系统的复杂度和开销,因为需要创建和维护代理对象。
  • 代理模式可能会降低系统的响应速度,因为每次调用真实对象的方法都需要经过代理对象。

动态代理模式

优点:

  • 动态代理可以在运行时动态地创建代理对象,而不需要事先定义代理类,这样可以减少代码量和提高开发效率。
  • 动态代理可以根据不同的目标对象和需求,灵活地生成不同的代理对象,这样可以增加系统的可扩展性和可维护性。
  • 动态代理可以实现对目标对象的透明访问,客户端只需要使用抽象主题的接口,而不需要关心真实对象和代理对象的细节。

缺点:

  • 动态代理需要使用反射和字节码技术来生成代理对象,这样会增加系统的复杂度和开销,也可能会影响系统的性能和稳定性。
  • 动态代理需要遵循一些约束和限制,例如JDK动态代理只能代理实现了接口的类,CGLIB动态代理不能代理final类或方法等,这样会降低系统的灵活性和通用性。
  • 动态代理比静态代理更难以理解和掌握,需要有一定的基础知识和经验才能使用好动态代理。

运用场景

  • 当我们需要访问一个远程对象时,可以使用远程代理,它可以隐藏远程对象的位置和通信细节,让客户端像访问本地对象一样访问远程对象。
  • 当我们需要创建一个开销很大的对象时,可以使用虚拟代理,它可以在真正需要的时候才创建真实对象,从而实现延迟加载和节省资源。
  • 当我们需要给一个对象增加一些额外的功能时,可以使用装饰代理,它可以在不修改原有对象的情况下,给对象添加一些新的行为或属性。
  • 当我们需要给一个对象增加一些访问控制或安全保护时,可以使用保护代理,它可以根据不同的用户或角色,对对象的访问进行限制或检查。
  • 当我们需要给一个对象增加一些日志记录或性能监控时,可以使用日志代理或性能代理,它可以在调用对象的方法之前或之后,记录相关的信息或数据。

总结

代理模式是一种常用的结构型设计模式,它可以让我们通过一个代理对象来间接访问一个真实对象,从而实现对目标对象的功能扩展或保护。代理模式有三个主要角色:抽象主题、真实主题和代理主题。代理模式有多种类型,例如静态代理、动态代理、远程代理、虚拟代理等。代理模式有自己的优缺点,使用时需要根据具体的场景和需求来选择合适的类型和方式。


http://www.ppmy.cn/news/61896.html

相关文章

工地烟火AI监控识别分析系统 yolov7

工地烟火AI监控识别分析系统通过yolov7网络模型技术,工地烟火AI监控识别分析系统对工地或者厂区现场监控区域内的烟火进行实时分析报警。YOLOv7 的发展方向与当前主流的实时目标检测器不同,研究团队希望它能够同时支持移动 GPU 和从边缘到云端的 GPU 设备…

惩治标题党,vue2监听父组件传过来的值,el-tree一键全选多个树形

vue2监听父组件传过来的值 父组件使用的动态组件&#xff0c;然后父传子 <component :is"checkedIt" :riskQuarterriskQuarter :riskYearriskYear></component> 子组件打印 console.log(riskQuarter :>> , this.$props.riskQuarter); 监听 pr…

vue前端开发100问(持续更新)

1.export default的作用是 export主要用于对外输出本模块变量的接口&#xff0c;一个文件就可以被理解为一个模块。export就是导出。 import就是在一个模块中加载另一个含有export接口的模块&#xff0c; import就是导入。 2.什么样的内容需要放在export default里面&#xf…

操作系统基础知识介绍之并行技术(包括指令级并行和数据级并行以及线程级并行和请求级并行)

一、相关概念 1.1 指令级并行 指令级并行是指在一个处理器内部&#xff0c;利用流水线、超标量、乱序执行等技术&#xff0c;使得多条指令可以同时或部分重叠地执行&#xff0c;从而提高指令的执行速度。比如&#xff0c;一个四级流水线可以同时执行四条指令的不同阶段&#…

const、指针、引用

一、const和指针&#xff1a; 分类&#xff1a; 1.1 指向常量的指针 上面的两种形式所表示的含义为&#xff1a;pt的指向可以随便修改&#xff0c;但pt所 指向的东西不得通过pt修改。 1.2 指向变量的常指针 指针的指向不允许改动&#xff0c;但指向的东西可以修改。&#…

【LeetCode】674. 最长连续递增序列

1. 问题 给定一个未经排序的整数数组&#xff0c;找到最长且连续递增的子序列&#xff0c;并返回该序列的长度。 连续递增的子序列 可以由两个下标 l 和 r&#xff08;l < r&#xff09;确定&#xff0c;如果对于每个 l < i < r&#xff0c;都有 nums[i] < nums[…

【R语言】鉴于计算10亿以内训练模型记录for循环的加速

文章目录 1 前言2 几个循环2.1 100以内的和2.2 100以内奇数和/偶数和 3 多重循环3.1 向量化3.2 合并循环3.3 apply函数3.4 矩阵运算3.5 foreach分解任务 4 讨论 1 前言 笔者主力机是MBAM1芯片&#xff08;8256&#xff09;&#xff0c;某个下午巩固循环突然思考到个问题&#…

前端配置化表单组件设计方法 | 京东云技术团队

一、背景 前端开发中涉及表单的页面非常多&#xff0c;看似功能简单&#xff0c;开发快速&#xff0c;实则占去了很大一部分时间。当某个表单包含元素过多时还会导致html代码过多&#xff0c;vue文件过大。从而不容易查找、修改和维护。为了提高开发效率及降低维护成本&#x…