当前位置: 首页 > news >正文

代理模式和单一职责原理一文读懂(设计模式与开发实践 P6)

文章目录

    • 代理模式
    • 实现
    • 保护代理
    • 虚拟代理
    • 单一职责原理
    • 代理和本体 - 接口一致性
    • 虚拟代理 - 合并请求
    • 缓存代理
    • 其他代理

代理模式

定义:为一个对象提供一个代用品 & 占位符,以便 控制对他的访问
关键:不方便直接访问某个对象或不满足需要的时候,提供一个对象来控制对那个对象的访问,我们则访问这个替身对象

实现

代理模式实现起来是相对容易的,让 xiaoming 送花给 anotherman

var Flower = function () {};var xiaoming = {// 送花给 targetsendFlower: function (target) {var flower = new Flower();target.receiveFlower(flower);},
};var anotherman = {// 代理人送花receiveFlower: function (flower) {MM.receiveFlower(flower);},
};var MM = {receiveFlower: function (flower) {console.log("收到花 " + flower);},
};xiaoming.sendFlower(anotherman);

此时的代理模式几乎毫无作用,中间人 / 代理人只是简单地转交给本体

但如果改变一下情景,如果中间人具有检测 MM 心情的能力,检测到 MM 心情好时再送花结果就不会不合时宜了!这使得一部分代码从 MM 和 xiaoming 身上得到了解耦,xiaoming 不会再被要求检测 MM 的心情,而 MM 也不被要求向 xiaoming 输出他的心情

保护代理

上面的代理模式可以演变成一个实用的例子,代理人 anotherman 可以帮助过滤一些请求,使得请求直接在 anotherman 处被拒绝掉,这就是 保护代理

虚拟代理

另外如果假设 flower 价值不菲,当你执行 new Flower() 时会消耗大量时间空间

那么我们把 new Flower() 的操作交给 anotherman 执行,这就叫做 虚拟代理,使得一些开销大的对象会在真正需要他时才创建

单一职责原理

当我们需要在页面加载图片,网速不够快的时候会需要在未加载好的位置放上一些文字或者其他内容,我们就可以用上代理模式

但这样的功能显然不需要代理模式也可以做到,我们可以引入单一职责原理帮助理解代理模式的好处在哪里

单一职责指的是:一个(通常也包括函数对象)应该仅有一个引起他变化的原因。如果这个类承担了多个职责,意味着这个对象将变得巨大,引起他变化的原因就有多个,导致脆弱和低内聚的设计

职责就是这个引起变化的原因,比如 MyImage 对象,除了要给 img 节点设置 src 来加载图片之外,还要负责预加载图片

但通过代理模式增加一个对象处理预加载,再获取 MyImage 对象,我们没有改变 MyImage 对象的行为同时,也增加了新的功能预加载,这也是开放-封闭原则的核心

代理和本体 - 接口一致性

如果某一天我们不需要预加载图像了,那么把代码直接从代理替换成本体,也是一样的:

  • 用户只需要放心请求,最终结果是相仿的
  • 任何本体和代理存在的地方都可以互相置换

在 Java 类似的语言中,代理和本体都显式实现了同一个接口,通过接口向上转型,避开了类型检查,所以都可以替换使用

在 JavaScript 中,有时通过鸭子类型来检测,有时则直接不检测,依赖程序员的自觉性,这还是在可控范围内的~

虚拟代理 - 合并请求

在 HTTP 中,有时我们会发送文件,如果一次有许多文件需要发送,频繁地请求必然会造成巨大的开销,我们就可以通过代理,收集一段时间的请求并一起打包给服务器

var sendFile = function () {console.log("send file");
};var proxySendFile = (function () {var cache = [];var timer;return function (id) {cache.push(id);if (timer) return;timer = setTimeout(function () {sendFile(cache.join(",")); // 2秒后向本体发送id集合clearTimeout(timer);timer = null;cache.length = 0; // 清空id集合});};
})();

缓存代理

缓存代理可以为一些开销大的运算提供临时的存储,如果下次请求参数一致,就直接返回

这样的例子在 ajax 异步请求 & 分页请求中是常见的!

var proxyMulti = (function () {var cache = {}; // 缓存return function () {var args = Array.prototype.join.call(arguments, ",");if (args in cache) {// 如果缓存中有这个参数return cache[args];}// 如果缓存中没有这个参数return (cache[args] = mult.apply(this, arguments));};
})();

其他代理

除此之外还有一些代理在 JavaScript 中不那么常见,但也很重要:

  • 防火墙代理:控制网络资源访问,避免坏人靠近
  • 远程代理:为一个对象在不同的地址空间提供局部代表
  • 保护代理:需要不同访问权限的情况
  • 智能引用代理:在访问对象时附加一些操作,比如计算对象被引用多少次
  • 写时复制代理:延迟了复制的过程,当对象被真正修改时才进行复制,DLL 是典型运用场景

相关文章:

代理模式和单一职责原理一文读懂(设计模式与开发实践 P6)

文章目录 代理模式实现保护代理虚拟代理单一职责原理代理和本体 - 接口一致性虚拟代理 - 合并请求缓存代理其他代理 代理模式 定义:为一个对象提供一个代用品 & 占位符,以便 控制对他的访问 关键:不方便直接访问某个对象或不满足需要的时…...

Linux网络编程|TCP编程

一.网络基础 1.1网络发展史 Internet-“冷战”的产物 1957年10月和11月,前苏联先后有两颗“Sputnik”卫星上天 1958年美国总统艾森豪威尔向美国国会提出建立DARPA (Defense Advanced Research Project Agency),即国防部高级研究计划署&#…...

FPGA----VCU128的DDR4无法使用问题(全网唯一)

1、在Vivado 2019.1版本中使用DDR4的IP核会遇到如下图所示的错误,即便过了implementation生成了bit,DDR4也无法正常启动。 2、解决办法,上xilinx社区搜一下就知道了 AMD Customer Communityhttps://support.xilinx.com/s/article/69035?lan…...

【毕设选题】flink大数据淘宝用户行为数据实时分析与可视化

文章目录 0 前言1、环境准备1.1 flink 下载相关 jar 包1.2 生成 kafka 数据1.3 开发前的三个小 tip 2、flink-sql 客户端编写运行 sql2.1 创建 kafka 数据源表2.2 指标统计:每小时成交量2.2.1 创建 es 结果表, 存放每小时的成交量2.2.2 执行 sql &#x…...

机器学习练习-决策树

机器学习练习-决策树 代码更新地址:https://github.com/fengdu78/WZU-machine-learning-course 代码修改并注释:黄海广,haiguang2000wzu.edu.cn 1.分类决策树模型是表示基于特征对实例进行分类的树形结构。决策树可以转换成一个if…...

分类预测 | Matlab实现基于LFDA-SVM局部费歇尔判别数据降维结合支持向量机的多输入分类预测

分类预测 | Matlab实现基于LFDA-SVM局部费歇尔判别数据降维结合支持向量机的多输入分类预测 目录 分类预测 | Matlab实现基于LFDA-SVM局部费歇尔判别数据降维结合支持向量机的多输入分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于局部费歇尔判别数据降维的L…...

Say0l的安全开发-代理扫描工具-Sayo-proxyscan【红队工具】

写在前面 终于终于,安全开发也练习一年半了,有时间完善一下项目,写写中间踩过的坑。 安全开发的系列全部都会上传至github,欢迎使用和star。 工具链接地址 https://github.com/SAY0l/Sayo-proxyscan 工具简介 SOCKS4/SOCKS4…...

使用FFmpeg+ubuntu系统转化flac无损音频为mp3

功能需求如上题,我们来具体的操作一下: 1.先在ubuntu上面安装FFmpeg:sudo apt install ffmpeg 2.进入有flac音频文件的目录使用下述命令: ffmpeg -i test.FLAC -c:a libmp3lame -q:a 2 output.mp3 3.如果没有什么意外的话,你就能看到你的文件夹里面已经有转化好的mp3文件了 批…...

I/O多路复用三种实现

一.select 实现 (1)select流程 基本流程是: 1. 先构造一张有关文件描述符的表; fd_set readfds 2. 清空表 FD_ZERO() 3. 将你关心的文件描述符加入到这…...

DataInputStream数据读取 Vs ByteBuffer数据读取的巨大性能差距

背景: 今天在查找一个序列化和反序列化相关的问题时,意外发现使用DataInputStream读取和ByteBuffer读取之间性能相差巨大,本文就来记录下这两者在读取整数类型时的性能差异,以便在平时使用的过程中引起注意 DataInputStream数据…...

org.apache.flink.table.api.TableException: Sink does not exists

FlinkSQL_1.12_用DDL实现Kafka到MySQL的数据传输_实现按照条件进行过滤写入MySQL_flink从kafka拉取数据并过滤数据写入mysql_旧城里的阳光的博客-CSDN博客 参考这篇文章,写了kafka到mysql的代码例子,因为自己改了表结构,运行下面代码&#x…...

【多线程】CAS 详解

CAS 详解 一. 什么是 CAS二. CAS 的应用1. 实现原子类2. 实现自旋锁 三. CAS 的 ABA 问题四. 相关面试题 一. 什么是 CAS CAS: 全称Compare and swap,字面意思:”比较并交换“一个 CAS 涉及到以下操作: 我们假设内存中的原数据 V,旧的预期值…...

卷积神经网络实现咖啡豆分类 - P7

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 目录 环境步骤环境设置包引用全局设备对象 数据准备查看图像的信息制作数据集 模型设…...

C++之默认与自定义构造函数问题(二百一十七)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

Docker从认识到实践再到底层原理(五)|Docker镜像

前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…...

【Flowable】任务监听器(五)

前言 之前有需要使用到Flowable,鉴于网上的资料不是很多也不是很全也是捣鼓了半天,因此争取能在这里简单分享一下经验,帮助有需要的朋友,也非常欢迎大家指出不足的地方。 一、监听器 在Flowable中,我们可以使用监听…...

spring-kafka中ContainerProperties.AckMode详解

近期,我们线上遇到了一个性能问题,几乎快引起线上故障,后来仅仅是修改了一行代码,性能就提升了几十倍。一行代码几十倍,数据听起来很夸张,不过这是真实的数据,线上错误的配置的确有可能导致性能…...

【rpc】Dubbo和Zookeeper结合使用,它们的作用与联系(通俗易懂,一文理解)

目录 Dubbo是什么? 把系统模块变成分布式,有哪些好处,本来能在一台机子上运行,为什么还要远程调用 Zookeeper是什么? 它们进行配合使用时,之间的关系 服务注册 服务发现 动态地址管理 Dubbo是…...

ChatGPT的未来

随着人工智能的快速发展,ChatGPT作为一种自然语言生成模型,在各个领域都展现出了巨大的潜力。它不仅可以用于日常对话、创意助手和知识查询,还可以应用于教育、医疗、商业等各个领域,为人们带来更多便利和创新。 在教育领域&#…...

Pytorch模型转ONNX部署

开始以为会很困难,但是其实非常方便,下边分两步走:1. pytorch模型转onnx;2. 使用onnx进行inference 0. 准备工作 0.1 安装onnx 安装onnx和onnxruntime,onnx貌似是个环境。。倒是没有直接使用,onnxruntim…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

日常一水C

多态 言简意赅&#xff1a;就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过&#xff0c;当子类和父类的函数名相同时&#xff0c;会隐藏父类的同名函数转而调用子类的同名函数&#xff0c;如果要调用父类的同名函数&#xff0c;那么就需要对父类进行引用&#…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...