代理设计模式

代理设计模式

在我之前的博客中,我探索了各种处理对象创建机制的创作设计模式。现在,是时候深入研究结构设计模式,它重点关注如何组合对象和类以形成更大的结构,同时保持它们的灵活性和高效性。让我们从代理设计模式开始

javascript 中的代理设计模式

代理设计模式是一种结构设计模式,它提供一个对象代表另一个对象。它充当控制对真实对象的访问的中介,添加附加行为,例如延迟初始化、日志记录、访问控制或缓存,而无需更改原始对象的代码。

javascript 中,代理是 proxy 对象提供的内置功能,允许您为属性访问、赋值、函数调用等基本操作定义自定义行为。

我们什么时候需要代理模式?

代理模式在以下情况下特别有用:

延迟初始化:您希望延迟创建资源密集型对象,直到需要它为止。访问控制:您需要控制对对象的访问,例如限制未经授权的访问或根据条件限制操作。日志记录:您想要记录对象上的操作(例如,属性访问或方法调用)。缓存:您想要缓存昂贵操作的结果以避免冗余计算。

代理模式的组成部分

主题: 定义真实对象和代理的公共操作的接口。realsubject: 执行实际工作的实际对象。代理: 控制对 realsubject 的访问的中介。

类比:

想象一下,您有一幅大画想要向客人展示,但需要花费很多时间才能从储藏室中取出它(因为它很重并且需要时间来搬运)。您决定使用这幅画的小明信片图像,在他们等待实际画作被获取时快速向他们展示,而不是每次都等待。

在这个比喻中:

大画是真实的物体(就像需要时间加载的图像)。明信片是代理(一种轻量级替代品,直到真实对象准备好为止)。一旦真正的画作准备好,您就可以向客人展示实际的画作。

现实世界的类比:

将房地产经纪人视为代理人。当你想买房子时,你不会立即参观每栋房子(加载实物)。相反,房地产经纪人(代理人)首先向您展示照片和描述。只有当你准备购买时(即,当你调用display()时),代理才会安排看房(加载实物)。

真实示例:图像加载(虚拟代理)

让我们使用 web 应用程序中的图像加载示例,我们希望延迟图像的加载,直到用户请求它(延迟加载)。代理可以充当占位符,直到加载真实图像。

以下是如何在 javascript 中实现代理设计模式。

示例:图像加载代理

// step 1: the real objectclass realimage {  constructor(filename) {    this.filename = filename;    this.loadimagefromdisk();  }  loadimagefromdisk() {    console.log(`loading ${this.filename} from disk...`);  }  display() {    console.log(`displaying ${this.filename}`);  }}// step 2: the proxy objectclass proxyimage {  constructor(filename) {    this.realimage = null; // no real image yet    this.filename = filename;  }  display() {    if (this.realimage === null) {      // load the real image only when needed      this.realimage = new realimage(this.filename);    }    this.realimage.display(); // display the real image  }}// step 3: using the proxy to display the imageconst image = new proxyimage("photo.jpg");image.display(); // loads and displays the imageimage.display(); // just displays the image (already loaded)

说明:

1)。真实图像:

realimage类代表实际图像。它以文件名作为输入,并模拟从磁盘加载图像的耗时过程(由 loadimagefromdisk 方法显示)。加载后,将使用显示方法来显示图像。

2)。代理图像:

proxyimage类充当realimage的替代品。它不会立即加载真实图像。它包含对真实图像的引用(但最初它是空的,因为真实图像尚未加载)。当您在代理上调用显示方法时,它会检查真实图像是否已加载。如果没有,它会先加载,然后显示。

3)。用法:

当我们创建 proxyimage 实例时,实际图像尚未加载(因为它是资源密集型的)。第一次调用 display 时,代理加载图像(使用 realimage 类),然后显示它。第二次调用display时,真实图片已经加载完毕,所以只显示图片,不再加载。

内置proxy对象

es6 代理由一个代理构造函数组成,该构造函数接受目标和处理程序作为参数

const proxy = new proxy(target, handler)

这里,target代表应用代理的对象,而handler是一个特殊的对象,定义了代理的行为。

处理程序对象包含一系列具有预定义名称的可选方法,称为陷阱方法(例如 apply、get、set 和 has),当对代理实例执行相应操作时,这些方法会自动调用。

让我们通过使用内置代理实现计算器来理解这一点

// Step 1: Define the Calculator class with prototype methodsclass Calculator {  constructor() {    this.result = 0;  }  // Prototype method to add numbers  add(a, b) {    this.result = a + b;    return this.result;  }  // Prototype method to subtract numbers  subtract(a, b) {    this.result = a - b;    return this.result;  }  // Prototype method to multiply numbers  multiply(a, b) {    this.result = a * b;    return this.result;  }  // Prototype method to divide numbers  divide(a, b) {    if (b === 0) throw new Error("Division by zero is not allowed.");    this.result = a / b;    return this.result;  }}// Step 2: Create a proxy handler to intercept operationsconst handler = {  // Intercept 'get' operations to ensure access to prototype methods  get(target, prop, receiver) {    if (prop in target) {      console.log(`Accessing property: ${prop}`);      return Reflect.get(target, prop, receiver); // Access property safely    } else {      throw new Error(`Property "${prop}" does not exist.`);    }  },  // Intercept 'set' operations to prevent mutation  set(target, prop, value) {    throw new Error(`Cannot modify property "${prop}". The calculator is immutable.`);  }};// Step 3: Create a proxy instance that inherits the Calculator prototypeconst calculator = new Calculator(); // Original calculator objectconst proxiedCalculator = new Proxy(calculator, handler); // Proxy wrapping the calculator// Step 4: Use the proxy instancetry {  console.log(proxiedCalculator.add(5, 3)); // Output: 8  console.log(proxiedCalculator.multiply(4, 2)); // Output: 8  console.log(proxiedCalculator.divide(10, 2)); // Output: 5  // Attempt to access prototype directly through proxy  console.log(proxiedCalculator.__proto__ === Calculator.prototype); // Output: true  // Attempt to modify a property (should throw an error)  proxiedCalculator.result = 100; // Error: Cannot modify property "result".} catch (error) {  console.error(error.message); // Output: Cannot modify property "result". The calculator is immutable.}

使用代理的最佳部分是:代理对象继承了原calculator类的原型。通过代理设置的陷阱来避免突变。

代码说明

1)。 原型继承:

代理不会干扰 **calculator ** 类的原始原型。通过检查 proxiedcalculator.proto === calculator.prototype 来确认这一点。结果将是true

2)。 处理 getoperations:

get 陷阱拦截代理对象上的属性访问。我们使用 reflect.get 安全地访问原始对象的属性和方法。

3)。 防止突变:

每当尝试修改目标对象上的任何属性时,设置陷阱都会引发错误。这确保了不变性。

4)。 通过代理使用原型方法:

代理允许访问加、减、乘、除等方法,所有这些方法都在原始对象的原型上定义。

这里要观察的要点是:

保留原型继承:代理保留对所有原型方法的访问,使其行为类似于原始计算器。防止突变: 设置陷阱可确保计算器对象的内部状态不会被意外更改。安全访问属性和方法: get 陷阱确保仅访问有效的属性,从而提高鲁棒性。

如果您已经做到了这一步,请不要忘记点赞❤️,并在下面发表评论以提出任何问题或想法。您的反馈对我来说至关重要,我很乐意听到您的来信!

以上就是代理设计模式的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1493397.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月19日 15:39:35
下一篇 2025年12月19日 15:39:49

相关推荐

  • 页面加载时图表显示异常,刷新后恢复正常,是怎么回事?

    样式延迟加载导致图表显示异常 问题: 在加载页面时,图表不能正常显示,刷新后才恢复正常。这是什么原因? 答案: 图表绘制时,CSS 样式文件或数据尚未加载完成,导致容器没有尺寸,只能使用默认最小值进行渲染。刷新时,由于缓存,加载速度很快,因此样式能够及时加载,图表就能正常渲染。 解决方案: 指定容器…

    2025年12月24日
    000
  • 使用 React 构建 Fylo 云存储网站

    介绍 在这篇博文中,我们将逐步介绍如何使用 react 创建一个功能丰富的云存储网站。该网站受 fylo 启发,提供了主页、功能、工作原理、感言和页脚等部分。在此过程中,我们将讨论用于构建这个完全响应式网站的结构、组件和样式。 项目概况 该项目由多个部分组成,旨在展示云存储服务。每个部分都是用 re…

    2025年12月24日 好文分享
    000
  • 使用 React 构建食谱查找器网站

    介绍 在本博客中,我们将使用 react 构建一个食谱查找网站。该应用程序允许用户搜索他们最喜欢的食谱,查看趋势或新食谱,并保存他们最喜欢的食谱。我们将利用 edamam api 获取实时食谱数据并将其动态显示在网站上。 项目概况 食谱查找器允许用户: 按名称搜索食谱。查看趋势和新添加的食谱。查看各…

    2025年12月24日 好文分享
    200
  • 黑暗主题的力量和性能优化:简单指南

    在当今的数字时代,用户体验是关键。增强这种体验的一种方法是在您的网站或应用程序上实施深色主题。它不仅看起来时尚,而且还可以提高现代设备的性能并节省电池寿命。让我们探索如何使用深色主题优化您的网站并提高性能。 为什么选择黑暗主题? 减少眼睛疲劳:深色主题对眼睛更温和,尤其是在弱光条件下。这使用户可以更…

    2025年12月24日 好文分享
    300
  • 不可变数据结构:ECMA 4 中的记录和元组

    不可变数据结构:ecmascript 2024 中的新功能 ecmascript 2024 引入了几个令人兴奋的更新,但对我来说最突出的一个功能是引入了不可变数据结构。这些新结构——记录和元组——改变了 javascript 中数据管理的游戏规则。它们提供了一种令人满意的方式来保持我们的数据健全、安…

    2025年12月24日
    100
  • 不惜一切代价避免的前端开发错误

    简介 前端开发对于创建引人入胜且用户友好的网站至关重要。然而,在这方面犯错误可能会导致用户体验不佳、性能下降,甚至出现安全漏洞。为了确保您的网站是一流的,必须认识并避免常见的前端开发错误。 常见的前端开发错误 缺乏计划 跳过线框 跳过线框图过程是一种常见的疏忽。线框图有助于在任何实际开发开始之前可视…

    2025年12月24日
    000
  • 如何克服响应式布局的不足之处

    如何克服响应式布局的不足之处 随着移动设备的普及和互联网的发展,响应式布局成为了现代网页设计中必不可少的一部分。通过响应式设计,网页可以根据用户所使用的设备自动调整布局,使用户在不同的屏幕尺寸下都能获得良好的浏览体验。 然而,尽管响应式布局在提供多屏幕适应性方面做得相当出色,但仍然存在一些不足之处。…

    2025年12月24日
    000
  • 掌握响应式布局的关键技巧和实践经验

    掌握响应式布局的关键技巧和实践经验 随着移动设备的普及和多样性,越来越多的用户选择使用手机、平板等移动设备浏览网页,这就使得响应式布局成为了现代前端开发中的重要技术之一。响应式布局的目标就是让网页能够自适应不同尺寸的屏幕,确保在任何设备上都能提供良好的用户体验。 要掌握响应式布局的关键技巧和实践经验…

    2025年12月24日
    200
  • 研究响应式布局的问题和优化方法

    响应式布局存在的问题及优化方法研究 随着移动互联网的飞速发展,越来越多的人使用移动设备来浏览网页。为了让网站在不同设备上都能提供良好的用户体验,响应式布局已经成为了现代网页设计的标准之一。然而,响应式布局在实践中还存在一些问题,本文将对这些问题进行探讨,并提出一些优化方法。 首先,对于较大规模的网站…

    2025年12月24日
    000
  • 如何通过响应式布局改善用户体验?

    响应式布局如何提升用户体验? 随着移动设备的普及,越来越多的用户习惯使用不同尺寸的屏幕来浏览网页。为了在各种设备上呈现出良好的用户体验,响应式布局应运而生。响应式布局是一种能够根据设备的屏幕尺寸和特性来自动调整网页布局的技术。通过响应式布局,可以实现在不同屏幕上的内容可读性和可用性的优化,从而提升用…

    2025年12月24日
    200
  • CSS属性实现响应式图片延迟加载的方法

    CSS属性实现响应式图片延迟加载的方法 在网页开发中,经常会遇到需要加载大量图片的情况,特别是在移动设备上。为了提高页面的加载速度和用户体验,延迟加载(lazy loading)图像成为一种常见的优化方法。 延迟加载是指在页面加载时,只加载可见区域的图像,而不加载整个页面上的所有图像。这样可以大大减…

    2025年12月24日
    000
  • html5怎么加php_html5用Ajax与PHP后端交互实现数据传递【交互】

    HTML5不能直接运行PHP,需通过Ajax与PHP通信:前端用fetch发送请求,PHP接收处理并返回JSON,前端解析响应更新DOM;注意跨域、编码、CSRF防护和输入过滤。 HTML5 本身是前端标记语言,不能直接运行 PHP 代码,但可以通过 Ajax(异步 JavaScript)与 PHP…

    2025年12月23日
    300
  • html5怎么插入文档_HT5用object或iframe嵌入PDF/Word文档显示【插入】

    可在HTML5中用iframe或object标签嵌入PDF,需设宽高及可访问路径;Word文档需借OneDrive等第三方服务代理渲染;须处理跨域限制并提供下载降级方案。 如果您希望在HTML5页面中嵌入PDF或Word文档并直接显示,可以使用或标签实现。以下是几种可行的嵌入方法: 一、使用ifra…

    2025年12月23日
    200
  • html5框架怎么设置_html5用iframe或div框架集嵌入子页面搭整体结构【设置】

    HTML5中应使用iframe、div+CSS、object或Web Components替代已废弃的frameset/frame;iframe支持同源嵌入,div+CSS结合JavaScript可动态加载内容,object提供降级支持,Web Components实现可复用嵌入。 如果您希望使用 …

    2025年12月23日
    000
  • jimdo怎么插入html5粒子效果_jimdo粒子效果html5库引入与参数调整【攻略】

    可在Jimdo通过自定义HTML区块引入tsparticles库实现动态粒子效果,或用内联SVG替代;需调整颜色、数量等参数适配主题,并修复脚本加载问题。 如果您希望在 Jimdo 网站中添加动态 HTML5 粒子效果(如背景浮动粒子、鼠标交互连线等),但发现 Jimdo 编辑器默认不支持直接嵌入 …

    2025年12月23日
    000
  • html5乱码怎么设置_html5用meta charset=utf-8设编码防页面乱码【设置】

    HTML5中文乱码需四步解决:一、在首行添加 如果您在浏览 HTML5 页面时遇到中文显示为乱码的情况,则可能是由于网页未正确声明字符编码。以下是解决此问题的步骤: 一、在 head 中添加 meta charset 声明 HTML5 推荐使用 meta charset=”UTF-8&#…

    2025年12月23日
    000
  • mac html5 怎么下载_mac浏览器直接打开html5文件无需额外下载【说明】

    Mac上HTML5文件被下载而非渲染,需检查文件关联、浏览器安全限制、使用Python服务器托管、验证编码与MIME声明、禁用干扰扩展。 如果您在 Mac 上使用浏览器打开 HTML5 文件时发现需要额外下载而非直接渲染,可能是由于文件关联设置、浏览器默认行为或文件路径问题导致。以下是解决此问题的步…

    2025年12月23日
    200
  • html5怎么指定路径_HTML5用相对或绝对路径指定图片视频等资源位置【指定】

    HTML5资源无法显示通常因路径错误,解决方法包括:一、相对路径(如src=”images/logo.png”);二、绝对路径(如src=”/media/video.mp4″);三、data URL内联小资源;四、base标签统一基准路径;五、避免fi…

    2025年12月23日
    000
  • 怎么设置html5标签_HTML5按语义用header/nav/main等标签设置结构【设置】

    应正确使用header、nav、main、article、section、aside和footer等HTML5语义标签构建网页结构:一、按顺序嵌套header→nav→main→footer;二、遵守嵌套规则,如main不得为article子元素;三、辅以ARIA属性增强可访问性;四、通过W3C验证…

    2025年12月23日
    000
  • html5怎样设计进度条组件_html5进度条制作与动态效果实现【教程】

    HTML5原生元素可直观展示任务进度,支持CSS定制样式、JavaScript动态更新、requestAnimationFrame平滑动画及结合XMLHttpRequest实现文件上传实时进度。 如果您希望在网页中直观展示任务完成进度,HTML5 提供了原生的 元素,同时支持通过 CSS 样式定制外…

    2025年12月23日
    000

发表回复

登录后才能评论
关注微信