大话设计模式——5.代理模式(Proxy Pattern)

1.定义

为其他具体对象提供一种代理用以控制对这个对象的访问,属于结构型模式。
UML图:
在这里插入图片描述

2.示例

生活中有许多的代理,如房产中介,房主出售的房子挂在中介处,中介帮忙寻找需要的客户,客户不需要直接接触房主。

1)Subject:房子

public interface House {/*** 卖房子*/void sell();
}

2)RealSubject:将要出售的别墅

public class Villa implements House {@Overridepublic void sell() {System.out.println("房东出售大别墅");}
}

3)Proxy:房产中介(静态代理)

public class HouseProxy implements House {private Villa villa = new Villa();@Overridepublic void sell() {findCustomers();villa.sell();}private void findCustomers() {System.out.println("寻找客户");}
}

4)client:客户端运行

public class Main {public static void main(String[] args) {// 无代理House villa = new Villa();villa.sell();System.out.println("----代理----");// 有代理House villaProxy = new HouseProxy();villaProxy.sell();}
}

在这里插入图片描述

2.1 采用动态代理

1)JDK动态代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JDKHouseProxy implements InvocationHandler {// 代理的目标类,运行时进行具体指定private Object targetObj;public Object newInstance(Object targetObj) {// 指定具体的目标类this.targetObj = targetObj;// 构建目标代理类return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("实现jdk动态代理 before");// 调用目标类方法Object result = method.invoke(targetObj, args);System.out.println("实现jdk动态代理 after");return result;}
}

2)CGLib动态代理

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class CGLibHouseProxy implements MethodInterceptor {public Object newInstance(Object targetObj) {// 创建代理Enhancer enhancer = new Enhancer();// 设置目标类为父类enhancer.setSuperclass(targetObj.getClass());// 设置代理类(回调)enhancer.setCallback(this);return enhancer.create();}@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("CGLib代理 before ");Object result = methodProxy.invokeSuper(o, objects);System.out.println("CGLib代理 after ");return result;}
}

3)运行结果

public class Main {public static void main(String[] args) {// 无代理House villa = new Villa();villa.sell();System.out.println("----代理----");// 有代理House villaProxy = new HouseProxy();villaProxy.sell();// jdk动态代理System.out.println("----JDK代理----");House jdkHouseProxy = (House) new JDKHouseProxy().newInstance(villa);jdkHouseProxy.sell();// CGLib代理System.out.println("----CGLib代理----");House cglibHouseProxy = (House)new CGLibHouseProxy().newInstance(villa);cglibHouseProxy.sell();}
}

在这里插入图片描述

静态代理:由程序或者特定工具生成源代码,在程序编译时已经确定目标类和代理类的关系。容易造成代码冗余,即每个目标类都需要为止创建一个代理类
动态代理:通过java的反射机制在程序运行期间动态的为目标类创建代理类。无需为每个目标类都创建一个代理类,使用更加灵活,具备很好的扩展性

  • JDK代理:目标类需要实现一个接口,为spring默认的代理方式。
  • CGLib代理:有时候目标类是没有实现接口的,那么就采用改方式进行代理。通过在内存中构建目标类的派生类,继承目标类的方法进行改写。采用继承的方式进行代理,因此如果目标类是final类,或者方法是private、static属性
3.总结
  • 无需修改代理的对象源码,符合开闭原则,可使系统具有较好的灵活性和可扩展性
  • 可以对代理的具体对象做增强处理,如增加一些功能等
  • 增加了系统的复杂性与调用过程的链路
4.代理模式 VS 装饰模式
  • 代理模式代理的是具体的对象,可保护目标对象与增强目标对象的功能
  • 装饰模式装饰的是一类对象,可对一类具有共同特点的对象进行控制和处理
  • 装饰模式适合于需要动态地给对象添加新功能的情况,代理模式适合于需要控制对对象访问的情况。

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

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

相关文章

银河麒麟服务器ky10 server wvp镜像制作

在线安装docker yum install docker -y cat >/etc/docker/daemon.json<<EOF{"registry-mirrors": ["https://registry.docker-cn.com","https://dockerhub.azk8s.cn","https://hub-mirror.c.163.com"]} EOF systemctl start …

php集成修改数据库的字段

1.界面效果 2.代码 <?phpecho <form action"" method"post"><label for"table">表名:</label><input type"text" id"table" name"table"><br><div id"fieldsContaine…

js【详解】async await

为什么要使用 async await async await 实现了使用同步的语法实现异步&#xff0c;不再需要借助回调函数&#xff0c;让代码更加易于理解和维护。 (async function () {// await 必须放在 async 函数中try {// 加载第一张图片const img1 await loadImg1()// 加载第二张图片co…

P1002 [NOIP2002 普及组] 过河卒

题目 原题目链接 题目描述 棋盘上 A A A 点有一个过河卒&#xff0c;需要走到目标 B B B 点。卒行走的规则&#xff1a;可以向下、或者向右。同时在棋盘上 C C C 点有一个对方的马&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河…

比较两组二维平面结构的演化

假设1个6*6的二维平面空间&#xff0c;这个空间的行和列只能按照1-2-3-4-5-6-1的顺序变换。这个平面上的物体只能平移。在这个空间里有力&#xff0c;在这些力的作用下&#xff0c;两个点按照 1-7的顺序运动。 - - - - - - - - - - - - - - - A - - - - - …

序列化相关知识总结

目录 一、序列化1.1 基本概念1.1.1 序列化1.1.2 反序列化1.1.3 数据结构、对象与二进制串1.1.4 序列化/反序列化的目的 1.2 几种常见的序列化和反序列化协议1.2.1 XML&SOAP1.2.2 JSON&#xff08;Javascript Object Notation&#xff09;1.2.3 Protobuf 二、安卓下的序列化…

ARMv8/ARMv9架构入门到精通-学习方法

目录 1、学习ARM基础知识2、学习ARM异常(中断)3、学习MMU4、学习Cache5、学习Trustzone和安全架构6、学习ARM架构和各类IP推荐 本文转自 周贺贺&#xff0c;baron&#xff0c;代码改变世界ctw&#xff0c;Arm精选&#xff0c; 资深安全架构专家&#xff0c;11年手机安全/SOC底层…

SpringMVC06、数据处理

6、数据处理 6.1、处理提交数据 1、提交的域名称和处理方法的参数名一致 提交数据 : http://localhost:8080/hello?namekuangshen 处理方法 : RequestMapping("/hello") public String hello(String name){System.out.println(name);return "hello";…

javase day02笔记

第二天课堂笔记 源文件的组成部分★★ 源文件外部结构 class 类名{}main方法 public static void main(String [] args){}main方法可有可无 没有main的情况&#xff0c;编译成功&#xff0c;运行失败&#xff0c;没有程序入口 多个main情况&#xff0c;编译报错&#xff0c;…

半监督 伪标签

什么是半监督学习 半监督学习也是一类更接近于人类学习方法的机器学习范式。试想这样一个场景&#xff0c;我们小时候学习识别小猫、小狗、汽车等等物品时&#xff0c;往往只需要父母进行一两次的指导&#xff0c;我们就能很准确地辨认出什么是猫狗。这背后有一个重要原因是&am…

抖音素材网站去哪下载?给你推荐六个抖音自媒体网站

各位抖音视频创作达人们&#xff0c;是否在苦苦寻觅那些能够点燃观众热情&#xff0c;让视频内容跃然屏上的素材宝库呢&#xff1f;此刻&#xff0c;你们的寻觅之旅将迎来终点&#xff01;我将向你们隆重推荐10个精心挑选的视频素材库&#xff0c;它们定能让你们的抖音视频如同…

Windows下安装pip

一、下载pip 官网地址&#xff1a;https://pypi.org/project/pip/#files 1.1、pip工具查找方法 单击官网首页“PyPi”选项 在弹出来的搜索框中输入“pip” 选择最新的pip版本&#xff0c;点进去 下载pip安装包包 二、安装pip 解压“pip-24.0.tar.gz”&#xff0c;进…

【Linux】常用操作命令

目录 基本命令关机和重启帮助命令 用户管理命令添加用户&#xff1a;useradd 命令修改密码&#xff1a;passwd 命令查看登录用户&#xff1a;who 命令查看登录用户详细信息 :w切换用户 目录操作命令cdpwd命令目录查看 ls [-al] 目录操作【增&#xff0c;删&#xff0c;改&#…

java通过poi-tl生成word

我看公司之前做电子合同&#xff0c;使用TIBCO jaspersoft做的报表模板&#xff0c;如果是给自己公司开发或者给客户做项目&#xff0c;这个也没有什么&#xff0c;因为反正模板是固定的&#xff0c;一次性开发&#xff0c;不用担心后续的问题。即使后期有调整&#xff0c;改一…

计算两帧雷达数据之间的变换矩阵

文章目录 package.xmlCMakeLists.txtpoint_cloud_registration.cc运行结果 package.xml <?xml version"1.0"?> <package format"2"><name>point_cloud_registration</name><version>0.0.0</version><descriptio…

九州金榜|孩子厌学的因素及解决办法

孩子在学习的过程中&#xff0c;遇到厌学这种情况非常容易见到&#xff0c;这也是孩子在成长的过程中经常遇到的烦恼。面对孩子的厌学&#xff0c;作为家长这时候不要慌乱&#xff0c;要做到分析孩子产生厌学的原因&#xff0c;在去寻找解决孩子厌学的办法。下面九州金榜家庭教…

【漏洞复现】大华ICC智能物联综合管理平台任意文件读取漏洞

Nx01 产品简介 大华智能物联综合管理平台 iConnection Center&#xff08;以下简称&#xff1a;ICC平台&#xff09;&#xff0c;是一套基于智能物联的综合业务管理平台软件&#xff0c;具备强大的后台服务能力&#xff0c;配套了B/S管理员端、C/S客户端、移动APP终端、小程序等…

vue中性能优化

目录 1. 编码优化 2. 源码优化 3. 打包优化 4. 利用 Vue Devtools 总结 Vue.js 作为一个强大的前端框架&#xff0c;提供了丰富的功能和工具来帮助开发者构建高效的 Web 应用。然而&#xff0c;在开发过程中&#xff0c;性能优化仍然是一个需要关注的问题。以下是对 Vue.j…

华为OD机考-C卷

文章目录 攀登者问题停车场最短路径 攀登者问题 24/03/09 20:50~23:10 攀登者喜欢寻找各种地图&#xff0c;并且尝试攀登到最高的山峰。地图表示为一维数组&#xff0c;数组的索引代表水平位置&#xff0c;数组的元素代表相对海拔高度。其中数组元素0代表地面。一个山脉可能有多…

GTH手册学习注解

CPLL的动态配置 终于看到有这个复位功能了 QPLL SWITCHing需要复位 器件级RESET没发现有管脚引出来 两种复位方式&#xff0c;对应全复位和器件级复位 对应的复位功能管脚 改那个2分频的寄存器说明段&#xff0c;复位是自动发生的&#xff1f;说明可能起效了&#xff0c;但是分…