设计模式(六)代理模式

相关文章
设计模式系列

1.代理模式简介

代理模式介绍

代理模式也叫委托模式,是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场景有很多,比如代购、代理上网、打官司等。

定义

为其他对象提供一种代理以控制这个对象的访问。

代理模式结构图

  • Subject:抽象主题类,声明真实主题与代理的共同接口方法。
  • RealSubject:真实主题类,定义了代理所表示的真实对象,客户端通过代理类间接的调用真实主题类的方法。
  • ProxySubject:代理类,持有对真实主题类的引用,在其所实现的接口方法中调用真实主题类中相应的接口方法执行。
  • Client:客户端类。

2.代理模式的简单实现

假设我要买一个BV的包(博主我很喜欢一直买不起),国内的太贵了,我找了个代购来帮我海外购买,这样能省好多钱,哈哈。

抽象主题类(Subject)

抽象主题类具有真实主题类和代理的共同接口方法,我想要代购,那共同的方法就是购买:

public interface IShop {//购买void buy();
}

真实主题类(RealSubject)

这个购买者LiuWangShu也就是我,实现了IShop接口提供的 buy()方法:

public class LiuWangShu implements IShop {@Overridepublic void buy() {System.out.println("购买");}
}

代理类(ProxySubject)

我找的代理类同样也要实现IShop接口,并且要持有被代理者,在buy()方法中调用了被代理者的buy()方法:

public class Purchasing implements IShop {private IShop mShop;public Purchasing(IShop shop){mShop=shop;}@Overridepublic void buy() {mShop.buy();}
}

客户端类(Client)

public class Client {public static void main(String[] args){//创建LiuWangShuIShop liuwangshu=new LiuWangShu();//创建代购者并将LiuWangShu作为构造函数传IShop purchasing=new Purchasing(liuwangshu);purchasing.buy();}
}

看完客户端类的代码,其实也是很好理解,就是代理类包含了真实主题类(被代理者),最终调用的都是真实主题类(被代理者)实现的方法,在上面的例子就是LiuWangShu类的buy()方法,所以运行的结果就是“购买”。

3.动态代理的简单实现

从编码的角度来说,代理模式分为静态代理和动态代理,上面的例子是静态代理,在代码运行前就已经存在了代理类的class编译文件,而动态代理则是在代码运行时通过反射来动态的生成代理类的对象,并确定到底来代理谁。也就是我们在编码阶段不需要知道代理谁,代理谁我们将会在代码运行时决定。Java提供了动态的代理接口InvocationHandler,实现该接口需要重写invoke()方法。下面我们在上面静态代理的例子上做修改:

创建动态代理类:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicPurchasing implements InvocationHandler{private Object obj;public DynamicPurchasing(Object obj){this.obj=obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result=method.invoke(obj, args);return result;}
}

在动态代理类中我们声明一个Object的引用,该引用指向被代理类,我们调用被代理类的具体方法在invoke()方法中执行。接下来我们修改客户端类代码:

import java.lang.reflect.Proxy;
public class Client {public static void main(String[] args){//创建LiuWangShuIShop liuwangshu=new LiuWangShu();//创建动态代理DynamicPurchasing  mDynamicPurchasing=new DynamicPurchasing(liuwangshu);//创建LiuWangShu的ClassLoaderClassLoader loader=liuwangshu.getClass().getClassLoader();//动态创建代理类IShop purchasing= (IShop) Proxy.newProxyInstance(loader,new Class[]{IShop.class},mDynamicPurchasing);purchasing.buy();}
}

4.代理模式的应用

代理模式类型

代理模式的类型主要有以下几点:

  1. 远程代理:为一个对象在不同的地址空间提供局部代表,这样系统可以将Server部分的事项隐藏。
  2. 虚拟代理:使用一个代理对象表示一个十分耗资源的对象并在真正需要时才创建。
  3. 安全代理:用来控制真实对象访问时的权限。
  4. 智能指引:当调用真实的对象时,代理处理另外一些事,比如计算真实对象的引用计数,当该对象没有引用时,可以自动释放它;或者访问一个实际对象时,检查是否已经能够锁定它,以确保其他对象不能改变它。
代理模式使用场景

无法或者不想直接访问某个对象时可以通过一个代理对象来间接的访问。

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

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

相关文章

Layer1 明星项目 Partisia Blockchain 何以打造互操作、可创新的数字经济网络

我们的目标是创建一个以用户为中心的全新数字经济网络:在去信任化和公平透明的环境下,所有的隐私数据都能够得到天然保障,企业、用户等各角色的协作与共享将会更顺利地进行。 —— Partisia Blockchain 团队 作为一个以 Web3 安全为技术方向的…

Linux学习之vi/vim详细介绍

目录 ​编辑 1. 什么是 vim? 2. vi/vim 的使用 2.1 命令模式 2.2 输入模式 2.3 底线命令模式 3. vi/vim 使用实例 3.1 使用 vi/vim 进入一般模式 3.2 按下 i 进入输入模式(也称为编辑模式),开始编辑文字 3.3 按下 ESC 按钮回到一般模式…

jenkins+kubernetes+git+dockerhub构建devops云平台

Devops简介 k8s助力Devops在企业落地实践 传统方式部署项目为什么发布慢,效率低? 上线一个功能,有多少时间被浪费了? 如何解决发布慢,效率低的问题呢? 什么是Devops? 敏捷开发 提高开发效率&…

CKA认证,开启您的云原生之旅!

在当今数字化时代,云计算已经成为企业和个人发展的关键技术。而获得CKA(Certified Kubernetes Administrator)认证,将是您在云原生领域迈出的重要一步。 CKA认证是由Kubernetes官方推出的权威认证,它旨在验证您在Kuber…

vue:实现顶部消息横向滚动通知

前言 系统顶部展示一个横向滚动的消息通知&#xff0c;就是消息内容从右往左一直滚动。 效果如下&#xff1a; 代码 使用 <template><div class"notic-bar"><img :src"notic" class"notice-img" /><div class"noti…

C++之类和对象(2)

目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 2. 赋值运算符只能重载成类的成员函数不能重载成全局函数 3. 用户没有显式实现时&…

【Flink CDC(一)】实现mysql整表与增量读取

文章目录 一. 运行前准备1. 依赖1.1. Maven dependency1.2. SQL Client JAR&#xff08;推荐&#xff09; 2. 配置 MySQL 服务器&#xff08;必须&#xff09; 二. 功能说明1. 启动模式2. 全量阶段支持 checkpoint3. 关于无主键表Exactly-Once 处理 三. 实战1. 实现mysql整表与…

如何用生成式AI创建食谱,解决五岁孩童挑食问题?

如何处理孩子挑食问题&#xff0c;对父母来说可能是一个挑战。这需要耐心、创造力和策略的结合。在深入具体策略之前&#xff0c;了解五岁儿童的口味偏好仍在发展中&#xff0c;他们的饮食行为受多种因素影响&#xff0c;包括气质、接触不同类型食物的程度以及父母对饮食的态度…

【ArcGIS】利用DEM进行水文分析:流向/流量等

利用DEM进行水文分析 ArcGIS实例参考 水文分析通过建立地表水文模型&#xff0c;研究与地表水流相关的各种自然现象&#xff0c;在城市和区域规划、农业及森林、交通道路等许多领域具有广泛的应用。 ArcGIS实例 某流域30m分辨率DEM如下&#xff1a; &#xff08;1&#xff09…

微服务学习

一、服务注册发现 服务注册就是维护一个登记簿&#xff0c;它管理系统内所有的服务地址。当新的服务启动后&#xff0c;它会向登记簿交待自己的地址信息。服务的依赖方直接向登记簿要Service Provider地址就行了。当下用于服务注册的工具非常多ZooKeeper&#xff0c;Consul&am…

【深入理解设计模式】装饰者设计模式

装饰者设计模式 装饰者设计模式&#xff08;Decorator Design Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许向现有对象添加新功能而不改变其结构。这种模式通常用于需要动态地为对象添加功能或行为的情况&#xff0c;而且这些功能可以独立于对象本身来进行扩展…

Selenium IDE插件录制网页,解放双手

1、 国内下载地址 https://www.crx4chrome.com/crx/77585/ &#xff0c;这个网络正常基本可以下载&#xff0c;目前最新版本是3.17.2。 点击Crx4Chrome下载。下载后的文件名称是&#xff1a;mooikfkahbdckldjjndioackbalphokd-3.17.2-Crx4Chrome.com.crx。 2、 安装 直接打开…

探索创造无限可能——Autodesk AutoCAD 2022(CAD 2022)系统要求

随着科技的不断进步和发展&#xff0c;计算机辅助设计&#xff08;CAD&#xff09;已经成为现代设计行业中不可或缺的一部分。在众多CAD软件中&#xff0c;Autodesk AutoCAD 2022&#xff08;CAD 2022&#xff09;无疑是最受欢迎和广泛应用的一款软件。作为一款全球领先的CAD软…

sql 行列互换

在SQL中进行行列互换可以使用PIVOT函数。下面是一个示例查询及其对应的结果&#xff1a; 创建测试表格 CREATE TABLE test_table (id INT PRIMARY KEY,name VARCHAR(50),category VARCHAR(50) );向测试表格插入数据 INSERT INTO test_table VALUES (1, A, Category A); INSE…

某电力铁塔安全监测预警系统案例分享

项目概述 电力铁塔是承载电力供应的重要设施&#xff0c;它的安全性需要得到可靠的保障。但是铁塔一般安装在户外&#xff0c;分布广泛&#xff0c;且有很多安装在偏远地区&#xff0c;容易受到自然、人力的影响和破环。因此需要使用辅助的方法实时监控铁塔的安全状态&#xff…

计算机设计大赛 深度学习大数据物流平台 python

文章目录 0 前言1 课题背景2 物流大数据平台的架构与设计3 智能车货匹配推荐算法的实现**1\. 问题陈述****2\. 算法模型**3\. 模型构建总览 **4 司机标签体系的搭建及算法****1\. 冷启动**2\. LSTM多标签模型算法 5 货运价格预测6 总结7 部分核心代码8 最后 0 前言 &#x1f5…

office word保存pdf高质量设置

1 采用第三方pdf功能生成 分辨率越大质量越好

MySQL集群 双主架构(配置命令)

CSDN 成就一亿技术人&#xff01; 今天刚开学第一天给大家分享一期&#xff1a;MySQL集群双主的配置需求和命令 CSDN 成就一亿技术人&#xff01; 神秘泣男子主页&#xff1a;作者首页 <———— MySQL专栏 &#xff1a;MySQL数据库专栏<———— MySQL双主是一…

Oracle 基础表管理(Heap-Organized Table Management)

表是数据库中负责数据存储的对象&#xff0c;在RDBMS中&#xff0c;数据以行、列的形式存储在表中。Oracle中表有很多种类型&#xff0c;最基础且应用最常用的类型就是堆表&#xff08;Heap-Organized Table&#xff09;&#xff0c;本文列举了Oracle堆表的常用管理操作。 一、…

pytorch --反向传播和优化器

1. 反向传播 计算当前张量的梯度 Tensor.backward(gradientNone, retain_graphNone, create_graphFalse, inputsNone)计算当前张量相对于图中叶子节点的梯度。 使用反向传播&#xff0c;每个节点的梯度&#xff0c;根据梯度进行参数优化&#xff0c;最后使得损失最小化 代码…