【代理模式】

代理模式介绍


代理模式的好处:

●可以是真实的角色的操作更加纯粹!不用去关注一些公共的业务
●公关也就交个代理角色!实现了业务的分工
●公共业务发生扩展的时候,方便集中管理
代理模式的缺点:
●一个真实角色就会产生一个代理角色;代码两会翻倍,开发效率会变低

静态代理

静态代理代码和理解:
可以将这个类理解为一个房东
* 房东因为生病急需用钱所以想将自己的房子快速租出去
* 但是,房东的资源比较少,想要及时将房子租出去需要花费时间,而自己需要马上去医院
* 所以将租房的工作代理给中介去执行

/*** 一个租房的接口* 该接口具有租房的方法(行为)*/
public interface IRentHouse {void rentHouse();
}

代理类:IntermediaryProxy 

/**-* 理解:这个类类似中介* 我也可以进行租房的操作,我可以代理房东进行租房* 我可不白干,需要点中介费*/
public class IntermediaryProxy implements IRentHouse{private IRentHouse iRent ;public IntermediaryProxy(IRentHouse IRentHouse){this.iRent = IRentHouse;}@Overridepublic void rentHouse(){System.out.println("交1000中介费~~~我今天内将房子租出去");iRent.rentHouse();System.out.println("我把房子租出去了:给你钱,中介费给你扣了-1000");}
}

被代理类:RentHouse 

/*** 代理模式* 可以将这个类理解为一个房东* 房东因为生病急需用钱所以想将自己的房子快速租出去* 但是,房东的资源比较少,想要及时将房子租出去需要花费时间,而自己需要马上去医院* 所以将租房的工作代理给中介去执行()**/
public class RentHouse implements IRentHouse{@Overridepublic void rentHouse(){System.out.println("实现租房");}
}
public class StaticTestMain {public static void main(String[] args){//模拟一个房东RentHouse landlord = new RentHouse();//模拟一个中介(代理将房租出去)IntermediaryProxy intermediaryProxy = new IntermediaryProxy(landlord);//执行租房的行为intermediaryProxy.rentHouse();}
}

动态代理

推荐视频:

狂神说的视频,对于动态代理讲解的很详细

记录一篇好的文章
java动态代理中的invoke方法是如何被自动调用的_zcc_0015的博客-CSDN博客

动态代理分为两大类:基于接口的动态代理,基于类的动态代理

  • 基于接口--JDK动态代理
  • 基于类的--cglib
  • java字节码实现:javasist

以下为JDK动态代理

最重要的两个类:Proxy和InvocationHandler

Proxy的作用:提供创建动态代理类的和实例的静态方法

InvocationHandler:处理代理实例,并返回结果的

动态代理的好处:

  • 可以是真实的角色的操作更加纯粹!不用去关注一些公共的业务
  • 公关也就交个代理角色!实现了业务的分工
  • 公共业务发生扩展的时候,方便集中管理
  • 一个动态代理类代理的是一个接口,一般对应着一类业务
  • 一个动态代理类可以代理多个类,只要实现了接口
/*** 一个租房的接口* 该接口具有租房的方法(行为)*/
public interface IRentHouse {void rentHouse();void needAgent(double money);
}
/*** 代理模式* 可以将这个类理解为一个房东* 房东因为生病急需用钱所以想将自己的房子快速租出去* 但是,房东的资源比较少,想要及时将房子租出去需要花费时间,而自己需要马上去医院* 所以将租房的工作代理给中介去执行()**/
public class RentHouse implements IRentHouse {@Overridepublic void rentHouse(){System.out.println("房东:支付的房租为:1000元!");System.out.println("实现租房");}@Overridepublic void needAgent(double money){System.out.println("房东内心os:没办法只能请中介");System.out.println("通过中介,获取的房租为:" + money+"元");}}

public static Object newProxyInstance(ClassLoader loader,

Class<?>[] interfaces,

InvocationHandler h)

参数一:用于指定用哪个类加载器,去加载生成的代理类,一般为被代理的对象

参数二:指定接口,这些接口用指定生成的代理有哪些方法,通常也为被代理对象的接口

参数三:用来指定生成的代理对象要干什么事情

代理对象干什么事儿都由invoke()方法决定

官方的解释:处理代理实例,并且返回结果

public Object invoke(

Object proxy,

Method method,

Object[] args) throws Throwable

参数一:代理对象,注意是代理对象,不是被代理对象

参数二:代理类对象调用的方法,被封装为的方法对象。此方法也就作为了被代理类对象要调用的方法

参数三:代理对象调用方法时,传递的实际参数

代理类(使用动态代理实现): 

public class DybanucTestMain {public static void main(String[] args){//模拟一个房东,被代理类RentHouse landlord = new RentHouse();//动态代理增强 landlord 对象/***我用动态代理,就不需要自己新建IntermediaryProxy(中介)对象,直接使用** 静态代理:有一个类文件来描述代理模式(此案例中就是IntermediaryProxy(中介)对象)* 动态代理:在内存中形成代理类** 三个参数:*ClassLoader loader =  landlord.getClass().getClassLoader(), 类的加载器,是哪个需要代理的类,Class<?>[] interfaces = landlord.getClass().getInterfaces(), 被代理类的实现的接口InvocationHandler h = new InvocationHandler() {}:当我们通过代理类的对象,调用方法时,会自动的调用如下的方法:invoke()*/IRentHouse proxy_landlord = (IRentHouse) Proxy.newProxyInstance(landlord.getClass().getClassLoader(), landlord.getClass().getInterfaces(), new InvocationHandler() {/*****主要是用来实现代理逻辑**参数:proxy :代理对象*     method:代理类对象调用的方法,被封装为的对象。此方法也就作为了被代理类对象要调用的方法*     args :代理对象调用方法时,传递的实际参数*将被代理类要执行的方法a的功能就声明在invoke()中*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable{//使用真实对象调用该方法if(method.getName().equals("needAgent")){System.out.println("中介:来来来。嘿嘿!找我帮你出租呀,今天就给你租出去了,但是要给我中介费5%");double money = (double) args[0];money = money * 0.95;Object obj = method.invoke(landlord, money);return obj;}else {System.out.println("中介:你没让我帮你找,就不用中介费了");Object obj = method.invoke(landlord, args);return obj;}}});//模拟通过自己将房子租出去//        proxy_landlord.rentHouse();//通过代理对象进行调用方法proxy_landlord.needAgent(1000);}
}

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

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

相关文章

【Git分支操作---讲解二】

Git分支操作---讲解二 查看分支创建分支切换分支修改分支切换分支合并分支合并分支【冲突】(只会修改主分支不会修改其他分支)什么时候会有冲突&#xff1f; 查看分支 创建分支 切换分支 修改分支 切换分支 合并分支 合并分支【冲突】(只会修改主分支不会修改其他分支) 什么时…

[Mac软件]Pixelmator Pro 3.3.12 专业图像编辑中文版

Pixelmator Pro是专为Mac设计的功能强大&#xff0c;美观且易于使用的图像编辑器。借助广泛的专业级无损图像编辑工具&#xff0c;Pixelmator Pro可使您发挥出最佳的照片效果&#xff0c;创建华丽的构图和设计&#xff0c;绘制&#xff0c;绘画&#xff0c;应用令人惊叹的效果&…

Git 的基本概念和使用方式

1、写在前面&#xff0c;这是使用CSDNAI创作助手 写的文档&#xff0c;供参考。 Git 是一个版本控制系统&#xff0c;可以记录文件的修改历史和版本信息。Git 有以下基本概念&#xff1a; 仓库&#xff08;Repository&#xff09;&#xff1a;Git 用仓库来存储文件的修改历史和…

【OpenGauss源码学习 —— 执行算子(Result 算子)】

执行算子&#xff08;Result 算子&#xff09; 控制算子Result 算子ExecInitResult 函数ResultState 结构体ExecInitResultTupleSlot 函数ExecAllocTableSlot函数 ExecResult 函数TupleTableSlot 结构体ExecProcNode 函数ExecProcNodeByType 函数ExecProject 函数 ExecEndResul…

【MyBatis】动态SQL > 重点:${...}和#{...}与resultMap和resultType的区别

目录 一、MyBatis动态sql 1.1 动态sql的作用 1.2 动态sql作用论证 1.2.1 条件判断&#xff1a;<if> 1.2.2 循环迭代&#xff1a;<foreach> 1.2.3 SQL片段重用 1.2.4 动态条件组合&#xff1a;<choose><when><otherwise> 1.2.5 <where…

解决问题:C++运行报错弹出白框

这个问题非常常见&#xff0c;很多情况可能会导致程序运行时弹出白框报错。以下是一些可能的原因和解决方法&#xff1a; 代码中存在语法错误或逻辑错误导致程序运行出错。解决方法是检查代码并修复错误。 程序依赖的库文件没有正确安装或加载。解决方法是检查程序依赖的库文件…

k8s分散部署节点之pod反亲和性(podAntiAffinity)

使用背景和场景 业务中的某个关键服务&#xff0c;配置了多个replica&#xff0c;结果在部署时&#xff0c;发现多个相同的副本同时部署在同一个主机上&#xff0c;结果主机故障时&#xff0c;所有副本同时漂移了&#xff0c;导致服务间断性中断 基于以上背景&#xff0c;实现…

UE4/5Niagara粒子特效之拖尾渐变

目录 开始操作 发射器一的制作 添加新的模块 ​编辑 让粒子长久存在 添加颜色 发射器二的制作 第三人称模板添加Niagara 效果 添加颜色 效果 隐藏第一个发射器 开始操作 首先创建一个粒子系统&#xff0c;用Fountain这个模板&#xff1a; 发射器一的制作 将不需要的…

力扣--数组类题目

1.两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任…

【大数据】Flink 详解(五):核心篇 Ⅳ

Flink 详解&#xff08;五&#xff09;&#xff1a;核心篇 Ⅳ 45、Flink 广播机制了解吗&#xff1f; 从图中可以理解 广播 就是一个公共的共享变量&#xff0c;广播变量存于 TaskManager 的内存中&#xff0c;所以广播变量不应该太大&#xff0c;将一个数据集广播后&#xff0…

代码随想录算法训练营(回溯总结篇)

回溯也可以说是暴力搜索&#xff08;最多剪枝一下&#xff09;。回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 一.分类 1.组合问题 &#xff08;1&#xff09;按组合元素的个数 &#xff08;2&#xff09;按组合元素的总和 有重复元素 同一元素可以重复选&#x…

数据库基本知识

基本概念 数据 描述事物的符号记录称为数据&#xff0c;数字&#xff0c;文字&#xff0c;图形&#xff0c;图像&#xff0c;声音&#xff0c;档案记录等都是数据 数据是以“记录”的形式按照统一的格式进行存储的&#xff0c;而不是杂乱无章的 相同格式和类型的数据统一存…

【LeetCode-中等题】3. 无重复字符的最长子串

题目 题解一&#xff1a;单指针&#xff0c;滑动窗口 思路&#xff1a; 设置一个左指针&#xff0c;来判断下一个元素是否在set集合中&#xff0c;如果不在&#xff0c;就加入集合&#xff0c;right继续&#xff0c;如果在&#xff0c;就剔除重复的元素&#xff0c;计算串的长度…

如何在Windows、Mac和Linux操作系统上安装Protocol Buffers(protobuf)编译器

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【PHP】PHP常见语法

文章目录 PHP简介前置知识了解静态网站的特点动态网站特点 PHP基础语法代码标记注释语句分隔(结束)符变量变量的基本概念变量的使用变量命名规则预定义变量可变变量变量传值内存分区 常量基本概念常量定义形式命名规则使用形式系统常量魔术常量 数据类型简单&#xff08;基本&a…

RISC-V(1)——RISC-V是什么,有什么用

目录 1. RISC-V是什么 2. RISC-V指令集 3. RISC-V特权架构 4. RiscV的寄存器描述 5. 指令 5.1 算数运算—add/sub/addi/mul/div/rem 5.2 逻辑运算—and/andi/or/ori/xor/xori 5.3 位移运算—sll/slli/srl/srli/sra/srai 5.4 数据传输—lb/lh/lw/lbu/lhu/lwu/sb/sh/sw …

Springboot+BeanSearcher

添加依赖 <dependency><groupId>cn.zhxu</groupId><artifactId>bean-searcher-boot-starter</artifactId><version>4.1.2</version> </dependency>Bean类 SearchBean(tables"user u, role r", where"u.role_…

管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——选言——相容选言——或

文章目录 第五章 选言命题:相容选言-或;不相容选言-要么要么第一节 选言-相容选言-或-推结论-A或B为真,则非A→B,非B→A(否一则肯一)真题(2010-28)-选言-相容选言-或-推结论-(1)A或B为真,A为假:得B为真(否一则肯一);真题(2012-29)-选言-相容选言-或-推结论-(1)…

spark的eventLog日志分析

查找满足指定条件的app_id查询条件: 表名、时间、节点名时间限定: 最好适当放大, 不知道什么原因有点不准eventLog的存放路径: spark.history.fs.logDirectory 1. spark-sql 先限定时间段;数据是逐行读入的, 但 app_id要按整个文件过滤, 按每个条件打标;按app_id粒度聚合, 查…

2023.8.8巨人网络数据开发工程师面试复盘

1 概述 问题一览 总体感觉良好&#xff0c;通过面试官的介绍可知这个岗位偏向离线数仓。 1.自我介绍 2.询问了其中一段实习经历 3.讲下你说用过的Linux命令 4.讲下HIVE的内部表和外部表有什么不同 *5.讲下你使用过的Hive函数&#xff08;好好在复习下多准备几个吧&#xff09…