一天攻克一个知识点 —— 设计模式之动态代理

一、设计模式之代理设计

代理设计是在Java开发中使用较多的一种设计模式,所谓的代理设计模式就是指一个代理主体操作真实主体,真实主体操作具体业务,代理主体负责给具体业务添砖加瓦。
就好比在生活中你有一套房子想要出租(你=真实主体),你找了房产中介(中介=代理主体)。真实主体负责提供房屋和收钱,代理主体负责带客户看房 、扣除手续费。租客只管租房子和付款,至于谁提供的房子并不关心。

我们发现,只需要定义一个租赁的接口,真实主体与代理主体都可以实现此接口,然后再由代理主体操作真实主体即可,上面的要求可以形成如下的代码:

1. 定义租赁接口

package com.javabasic.proxy;/*** 定义抽象接口*/
public interface House {/*** 定义抽象方法 租赁*/void rent();
}

2. 定义真实主体 - 房东

package com.javabasic.proxy;/*** 定义真实主体 房东*/
public class Owner implements House{@Overridepublic void rent() {System.out.println("房东提供房子,收取租金200元/月");}
}

3. 定义代理主体 - 中介

package com.javabasic.proxy;/*** 定义代理主体 中介*/
public class Agent implements House{// 接收真实主体 房东private House house;/*** 通过构造方法,让中介与房东之间产生联系。* 根据Java动态绑定机制,House运行时的真实类型是房东类型,就可以获取到房东的出租行为。* @param house*/public Agent(House house){this.house = house;}/*** 中介对房东出租业务进行增强*/@Overridepublic void rent() {rentBefore();house.rent(); // 房东 出租rentAfter();}private void rentBefore(){System.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");}private void rentAfter(){System.out.println("中介负责租客退租后的清扫工作。");}}

4. 主程序 中介出租房屋

在这里插入图片描述

二、动态代理

上面讲解的代理机制的操作,属于静态代理,因为每一个代理类只能为一个接口服务,这样程序开发中必然会产生过多的代理类。最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理功能。

Java 中想要实现动态代理的机制,则需要java.lang.reflect.InvocationHandler接口java.lang.reflect.Proxy类的支持。

InvocationHandler接口的定义如下:

package java.lang.reflect;public interface InvocationHandler {public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
}

Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类。

	/*ClassLoader loader : 类加载器Class<?>[] interfaces : 得到真实类实现的全部接口InvocationHandler h : 得到InvocationHandler子类实例*/@CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{...}

房屋租赁代码修改如下 :

1. 需要房东实现租赁的接口

public interface House {/*** 定义抽象方法 租赁*/void rent();
}public class Owner implements House{@Overridepublic void rent() {System.out.println("房东提供房子,收取租金200元/月");}
}

2. 创建代理类(InvocationHandler / Proxy)

package com.javabasic.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class Agent2 implements InvocationHandler {// 接收真实主体private Object obj;// 对外提供绑定真实主体方法public Object bind(Object obj){this.obj = obj;// 通过真实对象创建代理对象并返回给调用者。/*Proxy.newProxyInstance : 三个参数类加载器 :  this.obj.getClass().getClassLoader()真实类型实现的所有接口 : this.obj.getClass().getInterfaces()代理类  : thisreturn 代理对象*/Object object = Proxy.newProxyInstance(this.obj.getClass().getClassLoader(),this.obj.getClass().getInterfaces(), this);System.out.println("bind之后object真实类型 = " + object.getClass().getName());return object;}/*** 代理类会执行的方法。* @param proxy 代理主体* @param method 调用的方法* @param args 方法的参数** @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("proxy真实类型 = " + proxy.getClass().getName());rentBefore();method.invoke(this.obj, args); // 通过反射执行真实主体方法rentAfter();return null;}private void rentBefore(){System.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");}private void rentAfter(){System.out.println("中介负责租客退租后的清扫工作。");}
}

3. 主程序 出租

在这里插入图片描述

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

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

相关文章

安卓控件RecyclerVieW

文章目录 导入依赖简单使用实现横向滚动瀑布式 RecyclerView是官方在5.0之后新添加的控件&#xff0c;推出用来替代ListView和GridView的列表控件。为了保证RecyclerView在所有Android系统版本上都能使用。Google将RecyclerView控件定义在了AndroidX中&#xff0c;只需要在项目…

完美平替navicat的数据库软件DBeaver,免费开源,功能强大,使用简单

DBeaver Community 是一个免费的跨平台数据库工具&#xff0c;适用于开发人员、数据库管理员、分析师和所有与数据打交道的人。它支持所有流行的 SQL 数据库&#xff0c;如 MySQL、MariaDB、PostgreSQL、SQLite、Apache Family 等 1.到官网下载win版本直接安装 https://dbeav…

苹芯科技发布新AI模型,引领全球轻量级AI应用革命

苹芯科技&#xff0c;一家在全球AI技术领域中不断创新的公司&#xff0c;于2月28日宣布推出其最新研发的轻量级AI模型。这款新模型旨在为开发者和企业提供更高效、更易访问的人工智能工具&#xff0c;尤其强调在数据敏感和计算资源受限的环境下的应用潜力。 在谷歌刚刚推出Gemm…

Python使用cProfile进行性能分析使用详解

概要 在Python开发中,代码性能分析是优化和调试的重要环节。通过性能分析,可以找出程序中性能瓶颈,进而进行优化。cProfile是Python内置的性能分析工具,它可以详细地分析代码的执行时间和函数调用情况。本文将详细介绍如何使用cProfile进行代码性能分析,涵盖安装、基本用…

代码随想录第29天|贪心

134.加油站 代码随想录 代码随想录 索引01234gas12345cost34512 计算每个加油站的剩余油量&#xff0c;累计sum&#xff0c;一旦<0就从下一个重新计数。 我还没理解为什么我们不需要计算环路的sum&#xff0c;而是只需要遍历一次。 因为使用了两个变量&#xff1a;curSu…

力扣-46.全排列

刷力扣热题–第二十六天:46.全排列 新手第二十六天 奋战敲代码&#xff0c;持之以恒&#xff0c;见证成长 1.题目简介 2.题目解答 这道题目想了会,思路比较好想,但一直没调试成功,所以就参考了力扣官网的代码,积累一下回溯算法的实现和基本实现思路,即先试探后回溯,结果在下面…

加密软件通常使用哪些算法

加密软件通常使用多种算法来确保数据的安全性&#xff0c;这些算法主要分为对称加密算法、非对称加密算法和哈希算法三大类。 一、对称加密算法 对称加密算法&#xff0c;也称为共享密钥加密算法&#xff0c;是加密和解密都使用相同密钥的算法。这类算法的特点是加密和解密速…

24/8/4算法笔记 梯度下降

通过迭代地调整参数&#xff0c;沿着目标函数梯度的反方向&#xff08;即最陡峭的下降方向&#xff09;进行搜索&#xff0c;从而找到函数的局部最小值。 导入库 import matplotlib.pyplot as plt import numpy as np 构建方程和导数 #构建方程 f lambda x:(x-3.5)**2-4.…

使用Docker+ollama部署大模型

Docker的安装----在 Ubuntu 系统上安装 Docker 一&#xff1a;配置系统的 APT 软件包管理器 首先添加 Docker 的官方 GPG 密钥 # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/ke…

RabbitMQ未授权访问漏洞

RabbitMQ是目前非常热门的一款消息中间件&#xff0c;基于AMQP协议的&#xff0c;可以在发布者和使用者之间交换异步消息。消息可以是人类可读的JSON&#xff0c;简单字符串或可以转换为JSON字符串的值列表。 漏洞复现 使用以下Fofa语法对RabbitMQ产品进行搜索 port"15…

OpenCSG首发中文Chinese Mistral Large 2!

前沿科技速递&#x1f680; &#x1f389; 震撼发布&#xff01;OpenCSG再次微调发布CSG-Wukong-Chinese-Mistral-Large2-123B模型&#xff01; &#x1f50d; 本次工作基于mistral-large-instruct-2407进行微调&#xff0c;采用了尖端的训练技术和优化策略&#xff0c;确保模型…

Vulnhub靶机:JANGOW_ 1.0.1

目录 前言&#xff1a; 一、安装虚拟机Jangow&#xff1a;1.0.1靶机 二、Web部分 前言&#xff1a; 难度&#xff1a;简单&#xff0c;本文使用VirtualBox打开&#xff0c;下载地址&#xff1a; https://download.vulnhub.com/jangow/jangow-01-1.0.1.ova 一、安装虚拟机J…

数据结构与算法 - 二叉树

1. 概述 二叉树是这么一种树状结构&#xff1a;每个节点最多有两个孩子&#xff0c;左孩子和右孩子 完全二叉树&#xff1a;是一种二叉树结构&#xff0c;除了最后一层以外&#xff0c;每一层都必须填满&#xff0c;填充时要遵循从左到右 平衡二叉树&#xff1a;是一种二叉树…

Pip 使用报错及解决

pip install 是Python 包管理器命令&#xff0c;常用参数&#xff1a; -r&#xff1a;从一个需求文件中安装所有的包。-U 或 --upgrade&#xff1a;升级一个已经安装的包到最新版本。-I 或 --ignore-installed&#xff1a;即使包已经安装&#xff0c;也重新安装。--no-cache-d…

要想赚钱,AI模型该大该小?贾扬清:论AI模型经济学的技巧

卖模型就像感恩节卖火鸡&#xff0c;快才能赚钱。 最近的AI社区&#xff0c;关于模型规模的讨论有些活跃。 一方面&#xff0c;此前在大模型开发奉为“圣经”的Scaling Law&#xff0c;似乎正在褪去光环。去年大家还在猜测GPT-5的规模“可能会大到想不到”&#xff0c;现在这…

推荐一款界面优雅、功能强大的 .NET + Vue 权限管理系统

目录 前言 项目简介 项目特点 项目预览 项目演示 1、系统登录 2、系统首页 3、系统页面 4、插件示例 5、移动端 项目地址 总结 前言 今天推荐一款用 .NET 和 Vue3 实现的开源权限管理系统。它的界面清爽干净&#xff0c;功能强大&#xff0c;还具备灵活的角色权限分配…

19 注意力机制

目录 1.注意力机制从心理学的角度出发注意力机制非参注意力池化层Nadaraya-Watson 核回归:总结注意力汇聚:Nadaraya-Watson 核 代码实现非参数注意力汇聚(非参数注意力池化)注意力权重参数注意力汇聚(参数注意力池化)2.注意力分数如何将 key 和 value 拓展到更高的维度掩…

Bug 解决 | 后端项目无法正常启动,或依赖服务连接失败

目录 1、版本问题 2、依赖项问题 明明拷贝的代码&#xff0c;为什么别人行&#xff0c;我启动就报错&#xff1f; 这篇文章我就理一下最最常见的项目启动报错的两种原因&#xff01; 1、版本问题 比如明明项目的 Java 版本是 8&#xff0c;你非得拿 5 跑&#xff1f;那不是…

C++基础知识(入门章)

绪论 历经千辛万苦&#xff0c;我们终于来到了一个全新的板块---C。本期的内容主要是关于C的一些基础知识的初步了解。让我们一起努力&#xff0c;克服编程路上的艰难险阻&#xff0c;迎接属于自己成功的彼岸~ C的发展历史 1979年 C的起源可以追溯到1979年&#xff0c;当时B…

基于K210智能人脸识别+车牌识别系统(完整工程资料源码)

运行效果&#xff1a; 基于K210的智能人脸与车牌识别系统工程 目录&#xff1a; 运行效果&#xff1a; 目录&#xff1a; 前言&#xff1a; 一、国内外研究现状与发展趋势 二、相关技术基础 2.1 人脸识别技术 2.2 车牌识别技术 三、智能小区门禁系统设计 3.1 系统设计方案 3.2 …