JAVA SCRIPT设计模式--结构型--设计模式之Proxy代理模式(12)
创始人
2024-03-26 03:09:11
0

           JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代表全部的正确,特此声明。若读者需要了解设计模式目录、原则、设计变化方向,环境相关等信息请查看设计模式开篇。


一、UML类图

参与者:

1.1 Proxy(ImageProxy)

  • 保存一个引用使得代理可以访问实体。若RealSubject和Subject的接口相同,Proxy会引用Subject。
  • 提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。
  • 控制对实体的存取,并可能负责创建和删除它。

1.2 Subject(Graphic)

  • 定义RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。。

1.3 RealSubject(Image)

  • 定义Proxy所代表的实体。

二、意图

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

三、适用性 

  1. 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。
  2. 虚代理(Virtual Proxy)根据需要创建开销很大的对象。 
  3. 保护代理(ProtectionProxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
  4. 智能指引(SmartReference)取代了简单的指针,它在访问对象时执行一些附加操作。它的典型用途包括:对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它。
  • 当第一次引用一个持久对象时,将它装入内存。
  • 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

四、示例代码

4.1  动机

       对一个对象进行访问控制的一个原因是为了只有在我们确实需要这个对象时才对它进行创建和初始化。我们考虑一个可以在文档中嵌入图形对象的文档编辑器。有些图形对象的创建开销很大。但是打开文档必须很迅速,因此我们在打开文档时应避免 一次性创建所有开销很大的对象。因为并非所有这些对象在文档中都同时可见,所以也没有必要同时创建这些对象。

        这一限制条件意味着,对于每一个开销很大的对象,应该根据需要进行创建,当一个图像变为可见时会产生这样的需要。但是在文档中我们用什么来代替这个图像呢?我们又如何才能隐藏根据需要创建图像这一事实,从而不会使得编辑器的实现复杂化呢?例如,这种优化不应影响绘制和格式化的代码。

        问题的解决方案是使用另一个对象,即图像 Proxy,替代那个真正的图像。 Proxy可以代替一个图像对象,并且在需要时负责实例化这个图像对象。

        只有当文档编辑器激活图像代理的Draw操作以显示这个图像的时候,图像Proxy才创建真 正的图像。Proxy直接将随后的请求转发给这个图像对象。

      

4.2  示例UML

目录结构:

4.2 Proxy(ImageProxy)

import Graphic  from '../Graphic.js';
import MyImage  from './MyImage.js';
export default  class ImageProxy extends Graphic {fileName;extent;image;//被代理的js Image对象constructor(ctx,fileName,extent) {super(ctx ); this.fileName=fileName;this.extent=extent;}Draw() {if(this.image==null){console.log(` 图片Draw代理第一次被实际调用 `);this.LoadImage();}else{console.log(` 图片Draw已经被初始化后调用 `);return this.image.Draw();}}GetExtent(){if(this.image==null){console.log(` 获取图片的大小 ,用于计算站位空间`);return this.extent;}return this.image.GetExtent();}LoadImage(){this.image=new MyImage(this.ctx,this.fileName);this.image.Load();}} 

4.3 Subject(Graphic)

  • 定义RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。
export default  class Graphic {ctx;constructor(ctx) {this.ctx=ctx;  }Draw() {   }GetExtent(){}Store(){}Load(){}}

4.4 RealSubject(Image)

  • 定义Proxy所代表的实体。
import Graphic  from '../Graphic.js';export default  class MyImage extends Graphic {fileName;image;//被代理的js Image对象constructor(ctx,fileName) {super(ctx ); this.fileName=fileName; }Draw() {console.log(` 图片被画到画布上 `);this.ctx.drawImage(this.image,0,0); }GetExtent(){return {height:this.image.height,width:this.image.width} ;}async  Load(){console.log(` 图片加载。。。 `);this.image =new Image();this.image.src = this.fileName;this.image.onload=() => { 	 this.Draw();}	}} 

4.6 Client

import ImageProxy  from './Graphic/impl/ImageProxy.js';
export default class Client{main(ctx){let  imageProxy =new ImageProxy(ctx,'./hb.jpg',{height:950,width:1200});/**从代理获取图片大小**/console.log(` 第一次调用: 图片Draw  `);imageProxy.GetExtent();imageProxy.Draw();/**模拟等待三秒后,实际调用**/setTimeout(() => { 	 console.log(` 第二次调用:图片Draw  `);imageProxy.GetExtent();imageProxy.Draw();}	, 3000 )} }

4.7 测试HTML








测试结果:

Client.js:7  第一次调用: 图片Draw  
ImageProxy.js:26  获取图片的大小 ,用于计算站位空间
ImageProxy.js:15  图片Draw代理第一次被实际调用 
MyImage.js:21  图片加载。。。 
MyImage.js:12  图片被画到画布上 
Client.js:13  第二次调用:图片Draw  
ImageProxy.js:18  图片Draw已经被初始化后调用 
MyImage.js:12  图片被画到画布上 

五、源代码下载

        下载链接:https://pan.baidu.com/s/1XuPqp84cccBNVkbnMY3sKw 
         提取码:q2ut

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...