【地铁上的设计模式】--结构型模式:代理模式
什么是代理模式
代理模式是一种结构型设计模式,通过代理对象控制对原始对象的访问。代理对象充当客户端和实际对象之间的中介,隐藏了实际对象的复杂性,并提供了一些额外的控制。
在软件系统中,代理模式可以有多种应用。例如,代理模式可以用于实现远程代理、虚拟代理、保护代理和智能代理等。
远程代理是指代理对象用于在不同的地址空间中代表实际对象。虚拟代理是指代理对象在访问实际对象时先加载一些开销较小的信息,等到需要时再加载开销较大的信息。保护代理是指代理对象控制对实际对象的访问,以保护实际对象不被意外修改。智能代理是指代理对象在访问实际对象时,提供额外的服务,如缓存、日志、事务等。
代理模式有三个关键角色:抽象主题、实际主题和代理。抽象主题定义了实际主题和代理的公共接口。实际主题是实际要被代理的对象。代理对象持有实际主题的引用,并且可以在客户端请求时代理实际主题的访问。
代理模式的优点包括:
- 对客户端透明:客户端不需要知道实际主题的存在,而是通过代理对象访问实际主题。
- 减少系统开销:代理模式可以延迟实际主题的创建和加载,从而减少系统的开销。
- 提高系统可扩展性:通过使用代理模式,可以轻松地添加新的代理和实际主题,而不需要修改现有的代码。
代理模式的缺点包括:
- 增加系统复杂性:在设计时,需要考虑代理对象和实际对象之间的关系,这会增加系统的复杂性。
- 降低系统性能:由于代理模式需要额外的处理过程,可能会降低系统的性能。
- 增加代码量:代理模式需要编写额外的代码来实现代理对象和实际对象之间的交互,从而增加代码量。
如何实现代理模式
实现代理模式的步骤如下:
- 定义一个接口或抽象类,声明业务方法;
- 实现业务类,实现业务接口或抽象类;
- 实现代理类,代理类中包含对业务类的引用,并实现业务接口或抽象类;
- 在代理类中实现业务方法时,通过业务类对象的引用调用业务方法;
- 客户端只和代理类打交道,通过代理类间接访问业务类,实现对业务类的访问控制和增强。
通过代理模式,我们可以在不改变业务类的前提下,对业务方法进行访问控制和增强。代理模式可以分为静态代理和动态代理两种,其中静态代理需要编写代理类,而动态代理则是在运行时动态生成代理类,相对来说更加灵活。
Java实现
以下是Java实现代理模式的示例代码:
// 定义一个接口
public interface Subject {void doSomething();
}// 被代理类
public class RealSubject implements Subject {public void doSomething() {// 实现具体的业务逻辑}
}// 代理类
public class ProxySubject implements Subject {private RealSubject realSubject;public void doSomething() {if (realSubject == null) {realSubject = new RealSubject();}// 执行额外的操作,如权限控制、性能统计等realSubject.doSomething();}
}
在上面的代码中,Subject
是被代理类和代理类的共同接口,RealSubject
是被代理类,ProxySubject
是代理类。在ProxySubject
的doSomething()
方法中,会在调用被代理类的方法之前,执行一些额外的操作,比如权限控制、性能统计等。需要注意的是,代理类和被代理类要实现相同的接口,以便能够在客户端中互换使用。
需要使用代理模式的时候,只需要将实际的业务逻辑放在被代理类中实现,然后在代理类中引用被代理类,并在调用被代理类的方法之前添加一些额外的操作即可。
C#实现
以下是C#中实现代理模式的示例代码:
// 定义一个共同的接口
public interface ISubject
{void Request();
}// 定义实际主题
public class RealSubject : ISubject
{public void Request(){Console.WriteLine("RealSubject.Request() is called.");}
}// 定义代理
public class Proxy : ISubject
{private ISubject subject;public Proxy(ISubject subject){this.subject = subject;}public void Request(){if (subject == null){subject = new RealSubject();}Console.WriteLine("Proxy.Request() is called before RealSubject.Request().");subject.Request();Console.WriteLine("Proxy.Request() is called after RealSubject.Request().");}
}// 客户端
class Client
{static void Main(string[] args){ISubject proxy = new Proxy(null);proxy.Request();}
}
在以上示例代码中,我们定义了一个共同的接口 ISubject
,包含了代理和实际主题都必须实现的 Request()
方法。接着,我们定义了实际主题类 RealSubject
和代理类 Proxy
,并在代理类中持有了一个实际主题对象。
在代理类的 Request()
方法中,我们可以进行一些预处理,然后调用实际主题的 Request()
方法,并在调用结束后进行一些后续处理。这里我们使用了一个简单的判断,如果实际主题对象还没有被创建,就先创建一个实际主题对象。最后,在客户端中,我们实例化了一个代理对象,并调用了 Request()
方法。
总结
代理模式是一种结构型设计模式,它允许创建一个代理对象作为其他对象的接口。代理模式提供了一种中介机制,通过这种机制,代理对象可以控制访问其他对象的方式,并提供额外的功能。
代理模式的优点在于它可以降低系统中组件的耦合度,通过使用代理对象,客户端可以在不直接访问目标对象的情况下访问其方法。这有助于实现系统中的分层设计,保护目标对象免受不必要的访问,提高系统的安全性和可维护性。
另一个优点是代理对象可以提供额外的功能,比如在访问目标对象之前或之后执行某些操作,这样就可以在不影响目标对象的情况下实现对目标对象的定制化扩展。
然而,代理模式也有一些缺点,比如增加了系统中的额外代码量,导致了系统的复杂性增加。此外,代理对象还可能导致系统性能的下降,因为它需要在访问目标对象之前或之后执行额外的操作。
因此,在使用代理模式时,需要仔细权衡其优缺点,并选择适合自己应用场景的实现方式。
相关文章:
【地铁上的设计模式】--结构型模式:代理模式
什么是代理模式 代理模式是一种结构型设计模式,通过代理对象控制对原始对象的访问。代理对象充当客户端和实际对象之间的中介,隐藏了实际对象的复杂性,并提供了一些额外的控制。 在软件系统中,代理模式可以有多种应用。例如&…...
Oracle 体系结构
文章目录 Oracle体系结构Oracle的内存结构Oracle的进程结构服务器进程后台进程可选后台进程 物理存储结构逻辑存储结构 概念: Oracle server由Oracle instance和Oracle database组成,Oracle instance由后台进程和共享内存组成,Oracle的实例包…...
java手写日历系统(亲测)
package com.test.test02;import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Scanner;public class Test08 {//这是一个main方法,是程序的入口public static void main(String[] args) {//录入日期的StringScanner sc new Scanner…...
35-40的技术人员为什么会被“不友好”,请你们自身反思-拒做职场的“嗯嗯”怪
35-40真的是IT人员的一道坎吗? IT技术做不到35-40,可是我身边有大量35-40事业发达、职业发展更好的朋友。同时,我身边也有大量35-40被“毕业”的人更多。 本人经过7年来先后带队过3个大型研发团队,最少的也有60-70号人。最多的达到…...
工地烟火AI监控识别分析系统 yolov7
工地烟火AI监控识别分析系统通过yolov7网络模型技术,工地烟火AI监控识别分析系统对工地或者厂区现场监控区域内的烟火进行实时分析报警。YOLOv7 的发展方向与当前主流的实时目标检测器不同,研究团队希望它能够同时支持移动 GPU 和从边缘到云端的 GPU 设备…...
MATLAB算法实战应用案例精讲-【人工智能】对比学习(概念篇)(补充篇)
目录 前言 几个高频面试题目 基于对比学习(ContrastiveLearning)的文本表示模型【为什么】能学到文本【相似】度? 为什么对比学习能学到很好的语义相似度? 那么如何评价这个表示空间的质量呢? 知识储备 监督学习和非监督学习 算法原理…...
代码随想录算法训练营第三十一天 | 贪心1,想不到怎么找局部最优就做不出来
贪心算法理论基础 代码随想录 (programmercarl.com) 贪心算法理论基础!_哔哩哔哩_bilibili 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额ÿ…...
【SVN】版本控制管理的文件(夹)如何重命名
目录 一、前言二、操作步骤1. 使用SVN重命名(SVN rename)2. 输入新名称3. 确定重命名4. 立刻进行一次提交(commit)5. 补充 三、可能遇到的问题1. 情况一2. 情况二3. 情况三 一、前言 如果只是在本地的文件系统中修改SVN中的文件&a…...
必须包含数字,字母组合的密码正则表达式
输入要求:由数字和字母组成,并且要同时含有数字和字母,且长度要在2-64位之间。 ^(?![0-9]$)(?![a-zA-Z]$)[0-9A-Za-z]{2,64}$ 分开来注释一下: ^ 匹配一行的开头位置 (?![0-9]$) 预测该位置后面不全是数字 (?![a-zA-Z]$) 预…...
JavaScript:栈和对列
文章目录 栈和对列Js 有栈与队列吗20. 有效的括号 - 力扣(LeetCode)思路 1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)思路代码分析array.join() 操作打印const s of str 操作遍历 150. 逆波兰表达式求值 - 力扣…...
[数据库系统] 一、创建表以及使用主键约束(educoder)
1.任务:在数据库中创建一个表。 2.需要掌握: 如何在指定数据库中创建表。 知识点:如何在指定数据库中创建表。 我们先来了解一下在数据库中创建表的规则: CREATE TABLE 表名(字段名,数据类型,字段名,数据类型,.....) 例如&…...
《走进对象村4》之面向对象的第一大特性——封装
文章目录 🚀文章导读1、封装的概念2、访问限定修饰符3、如何进行封装4、封装的优点: 🚀文章导读 在本篇文章中,将详细的对封装进行总结,文章仅仅是个人的一些理解,如果有错误的地方,还望指出看完…...
罗马数字转整数、整数转罗马数字----2023/5/4
罗马数字转整数----2023/5/4 1.罗马数字转整数 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D …...
2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能。
2023-05-04:用go语言重写ffmpeg的scaling_video.c示例,用于实现视频缩放(Scaling)功能。 答案2023-05-04: 这段代码实现了使用 libswscale 库进行视频缩放的功能。下面是程序的主要流程: 1.获取命令行参…...
QT Android QTextEdit 复制粘贴文本后出现多余数据问题
目录 问题原因解决方法 问题 QT Android QTextEdit 长按选中文本后,点击复制,然后粘贴到手机便签或者QQ中,出现多余数据 例如,要复制的文本为 只因你太美 但实际在便签中粘贴后的文本为 只因你太美 p, li { white-space: pre-wra…...
知识变现海哥:你为什么努力却不富有,大概率是你不懂这个道理
要有价值观念,要有交换思维。商业的本质都是基于价值交换,你能为别人提供多少价值,你就能赚多少米,你帮助别人处理的问题越多你越有价值,你能成就多少人你就能被多少人成就。这是商业行为的底层逻辑。 你没赚到米 一是…...
【Mybatis】增删改查
1.添加相应的jar包 2.创建持久化类 在src目录下创建一个名为com.mybatis.po的包 创建持久化类MyUser,包含三个属性(uid,uname,usex) package com.mybatis.po; /***springtest数据库中user表的持久化类*/ public class MyUser {private Integer uid;//主键private…...
20230504----重返学习-vue2项目-跳转拦截-重定向并返回前一页-使用vuex调用接口-全选与全不选-总价计算
day-061-sixty-one-20230504-vue2项目-跳转拦截-重定向并返回前一页-使用vuex调用接口-全选与全不选-总价计算 vue2项目 跳转拦截 设置跳转拦截,比如在用户没token时,不能进入具体详情页,而是进入登录页进行登录。 跳转拦截具体思路 前端…...
(异或相消)猫猫数字异或和
E - Red Scarf (atcoder.jp) 刚入坑写的一道题被我拉出来对比分析了 我的思路: 垃圾运气选手凭借直觉乱搞猜出来的,没有思路。 题解思路: 由问题陈述中XOR的定义,我们可以看出计算3个或更多整数的XOR可以以任意顺序进行&#…...
树脂塞孔有哪些优缺点及应用?
树脂塞孔的概述 树脂塞孔就是利用导电或者非导电树脂,通过印刷,利用一切可能的方式,在机械通孔、机械盲埋孔等各种类型的孔内进行填充,实现塞孔的目的。 树脂塞孔的目的 1 树脂填充各种盲埋孔之后,利于层压的真空下…...
【Robot Framework】RF关键字大全
收录工作当中最常用的Robot Framework关键字 内容较多,可以CtrlF快速搜索自己想要的 1. RF循环使用(FOR循环) {list1} create list LOG TXT INI INF C CPP JAVA JS CSS LRC H ASM S ASP FOR ${file_type} IN {list1} log 构造请求参数 ${t…...
Xilinx Artix-7【XC7A35T-2CSG324I】【XC7A35T-1CSG324I】成本与收发器优化的FPGA器件
产品介绍: Xilinx Artix -7系列 FPGA 重新定义了成本敏感型解决方案,功耗比上一代产品降低了一半,同时为高带宽应用提供一流的收发器和信号处理能力。这些设备基于 28 纳米 HPL 工艺构建,提供一流的性能功耗比。与 MicroBlaze™ 软…...
K8S之自定义Controller
简介 在此之前我们先来了解下kubernetes的两个概念"声明式API"和"控制器模式"。"声明式API"核心原理就是当用户向kubernetes提交了一个API对象的描述后,Kubernetes会负责为你保证整个集群里各项资源的状态,都与你的API对象…...
无线电相关的SCI期刊有哪些? - 易智编译EaseEditing
以下是几个无线电相关的SCI期刊: IEEE Transactions on Wireless Communications: 这是一个IEEE无线通信协会的期刊,主要涵盖了无线通信领域的最新研究进展,包括无线网络,通信系统和信号处理等方面。 IEEE Transacti…...
Rust - 结构体基本使用
基础代码示例 为了理解何时需要使用结构体,官方文档给了一个案例,就是计算长方形的面积,这里我们会一步一步的重构代码直到使用结构体为止。 计算长方形的面积的具体逻辑就是获取长方形的宽度和高度,然后通过公式计算出长方形的…...
29. Kubernetes 核心组件讲解——Controller Manager
本章讲解知识点 Controller Manager 概述Replication ControllerNode ControllerResourceQuota ControllerNamespace ControllerService Controller 与 Endpoint Controller1. Controller Manager 概述 1.1 基本概念 一般来说,智能系统和自动系统通常会通过一个“操作系统”…...
BetaFlight统一硬件配置文件研读之feature命令
BetaFlight统一硬件配置文件研读之feature命令 1. 源由2. 代码分析3. 实例分析4. 配置情况4.1 feature4.2 feature list4.3 feature feature_name4.4 feature -feature_name 5. 参考资料 统一硬件配置文件的设计是一种非常好的设计模式,可以将硬件和软件的工作进行解…...
ChatGPT 不好用?那你看下这份 Prompt 工程指南
作为大型语言模型接口,ChatGPT 生成的响应令人刮目相看,然而,解锁其真正威力的关键还是在于提示工程。 在本文中,我们将揭示制作提示的专家级技巧,以生成更准确、更有意义的响应。无论你使用 ChatGPT 是为了服务客户、…...
冲浪杂记——
华为od是指什么? 华为OD(Open Developer Platform)是华为面向全球开发者推出的开放平台,旨在为开发者提供丰富的技术资源和开发工具,支持开发者快速构建基于华为技术的应用程序、解决方案和服务。华为OD平台为开发者提…...
深入理解Python中的进程与线程
前言 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务并发的执行,从而…...
镇江市扬中市做网站/做公司网站需要多少钱
P14.1-Promise入门介绍 1.概述 文章目录P14.1-Promise入门介绍1.概述1.1.什么是Promise1.2.什么是异步事件2.Promise处理异步事件基本使用2.1.创建Promise对象2.2.Promise对象封装异步代码2.3.Promise对象封装异步代码优化2.4.Promise对象resolve参数处理异步请求成功返回的数…...
西樵建网站/哈尔滨seo推广优化
好的数据库设计一定是精致、优雅、赏心悦目、让人心醉。 为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。,以提升数据库的存储效率、数据完整性和可扩展性…...
免费商标图案设计logo/百度seo公司哪家强一点
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼解N元一次方程从文件读入整数 N, 然后读入N*( N1)矩阵,得到解并输出到文件中。int main(){int ch;printf("\n");printf(" Gaussian Matrix Cal \n");printf("\n");printf("Choose:…...
wordpress分享到/网络营销的特点
Redis是一个不错的缓存数据库,读取数据速度效率都很不错。今天大家共同研究下redis的用法。结合网上的资料和自己的摸索,先来看下安装与配置把。 咱们主要看在WINDOWS上怎样使用REDIS数据库。 下载地址:https://github.com/dmajkic/redis/dow…...
做rap的网站/优化设计答案大全
2014-03-06 Created By BaoXinjian 一、摘要 检查点将进程的当前读写位置存储在磁盘中用于恢复目的。 检查点不仅可以真实地标记 Extract进程捕获的要进行同步的数据变化以及 Replicat进程应用到 target数据库的数据变化,防止进程进行冗余的数据处理,还可…...
信息分类网站好建吗/互联网广告营销是什么
public class User {public static void main(String[] args) {//i行号for (int i 1;i < 9;i){//j列号for (int j 1;j < i;j) {System.out.println(i "*" j "" i * j " ");}System.out.println();//换行}} }...