JAVA SCRIPT设计模式--结构型--设计模式之Proxy代理模式(12)

news2024/11/15 8:38:04

           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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
 
 
 <script  type="module" >
 import Client  from './Client.js'; 
 var x=document.getElementById("mycanvas")
 var ctx=x.getContext("2d") //create 2d object
let cl=new Client();
cl.main(ctx)

 </script>
</head>
<body>
<canvas id="mycanvas" width=900px height=900px></canvas>
    
</body>
</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

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

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

相关文章

搭建LNMP平台实现负载均衡与高可用

目录 环境要求 安装服务 搭建服务 1. nfs主机操作 2. web1主机操作 3. web2主机操作 4. php主机操作 5. mysql主机操作 6. 验证1 7. lb1主机操作 8. lb2主机操作 9. 验证2 测试1 测试2 网站故障解决 验证 环境要求 实验目标&#xff1a;搭建LNMP平台实现负载均衡与高可用。 拓…

web课程设计——健身俱乐部健身器材网站模板(24页)HTML+CSS+JavaScript

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

解析Vue项目每一个文件夹及文件的作用

使用vue-cli2.x脚手架为每个vue项目创建脚手架项目结构&#xff0c;项目结构目录中每个文件夹介绍如下&#xff1a; 1、build 文件夹 里面是对 webpack 开发和打包的相关设置&#xff0c;包括入口文件&#xff0c;输出文件&#xff0c;使用的模块等。 1.1 webpack.base.conf.j…

人大金仓 +用友:助力企业数智化转型,实现高质量发展

金兰组织联合解决方案集数字化浪潮下&#xff0c;联合解决方案已经成为这个时代的必然选择。如何依托各自产品的功能与特点&#xff0c;持续优化和完善解决方案能力&#xff0c;满足客户更多、更复杂的业务诉求&#xff0c;成为数字服务厂商的重要工作内容。为此&#xff0c;金…

我的电脑图标没了怎么办?3个方法找回消失的图标

最近&#xff0c;很多小伙伴都在私信小编&#xff0c;说他们的电脑桌面图标不见了。我的电脑图标没了怎么办&#xff1f;别担心。图标突然消失了&#xff0c;很可能是你不小心隐藏了桌面图标。这里有3个方法可以帮助你快速恢复并找到电脑图标&#xff0c;一起来看看吧&#xff…

现代基准测试程序种类以及使用方法

文章目录基准测试程序种类常见测试程序概述常见测试程序使用Dhrystone的使用UnixBench的使用CPU-Z的安装与使用参考文献现代计算机的性能测量极大地依赖于在其上运行的工作负载&#xff0c;为了测量和分析计算机系统的性能人们常常选择或构造一组能反映其工作负载特征的程序&am…

python文件转换成exe可执行的windows文件

一、介绍 python的程序需要运行环境有时候很不方便&#xff0c;因为要交给别人代码可能因为环境的原因运行各种问题&#xff0c;这里给出直接讲python程序转换成exe文件&#xff0c;很方便直接给执行程序就可以&#xff0c;也不用担心运行环境问题而运行不了 二、工具 1、安装…

[奶奶看了都会]ChatGPT保姆级注册教程

大家好&#xff0c;我是小卷 最近几天OpenAI发布的ChatGPT聊天机器人火出天际了&#xff0c;连着上了各个平台的热搜榜。这个聊天机器人最大的特点是模仿人类说话风格同时回答大量问题。 有人说ChatGPT是真正的人工智能&#xff0c;它不仅能和你聊天&#xff0c;还是写小作文…

[附源码]Python计算机毕业设计SSM基于微信平台的匿名电子投票系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

web课程设计网页规划与设计 HTML+CSS+JavaScript仿英雄联盟LOL首页(1个页面)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

第4季4:图像sensor的驱动源码解析

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、sensor驱动源码的框架 mpp定义了一整套sensor驱动的实现和封装&#xff0c;这里以ar0130型号的sensor为例进行说明。 1、sensor层驱动 &#xff08;1&#xff09;sensor层驱动位于mpp/componen…

Java基础面试题

请介绍全局变量和局部变量的区别 Java中的变量分为成员变量和局部变量&#xff0c;它们的区别如下&#xff1a; 成员变量&#xff1a; 成员变量是在类的范围里定义的变量&#xff1b;成员变量有默认初始值&#xff1b;未被static修饰的成员变量也叫实例变量&#xff0c;它存储于…

知识图谱-KGE-语义匹配-双线性模型-2019:TuckER

【paper】 TuckER: Tensor Factorization for Knowledge Graph Completion【简介】 这篇文章是英国爱丁堡大学的研究者发表于 ICML 2019 上的文章&#xff0c;提出了 TuckER&#xff0c;是一个线性的张量分解模型&#xff0c;对表示三元组事实的二值张量做 Tucker 分解。 背景…

python中nmupy获取本地数据和索引

1. numpy读取数据 可以使用numpy中的loadtxt进行数据读取&#xff0c;所包含的参数如下 参数名解释frame文件&#xff0c;字符串等也可以是.gz或bz2压缩文件dtype数据类型&#xff0c;即CSV中字符串以什么数据类型读入数组中&#xff0c;默认是np.floatdelimiter分隔字符串&a…

CAS:2379387-10-5;TPE-丙烯酰胺;AIE聚集诱导发光

英文名称:2-Propenamide,N-[4-(1,2,2-triphenylethenyl)phenyl]- 英文同义词:2-Propenamide,N-[4-(1,2,2-triphenylethenyl)phenyl]- CAS号:2379387-10-5 分子式:C29H23NO 分子量:401.5 结构式&#xff1a; AIE聚集诱导发光材料的特点&#xff1a; 1.在固态下有强发光特性&…

Typecho-handsome主题如何统计全站字数

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…

phpstudy2020安装及简单使用教程

phpstudyV8.0以上使用教程 简介安装步骤配置搭建网站自己的第一个PHP程序 最新版长这样 简介 按我的理解&#xff0c;phpstudy是一个集成式的PHP运行环境&#xff0c;虽然是个软件&#xff0c;但他实现的功能就是给PHP语言编写的脚本赋予一个可执行的环境&#xff0c;可以…

GPR(高斯过程回归)

写在前面&#xff1a;   本文为科研理论笔记的第三篇&#xff0c;其余笔记目录传送门&#xff1a; 理论笔记专栏目录 介绍结束下面开始进入正题&#xff1a; 1 高斯分布 ​   一元高斯分布的概率密度函数为&#xff1a; p(x)1σ2πexp⁡(−(x−μ)22σ2);简写为&#xff…

Lecture2:损失函数及优化

目录 1.损失函数 1.1 支持向量机SVM 1.1.1 SVM的代价函数及优化目标 1.1.2 如何理解将SVM成为大间距分类器 1.1.3 大间距分类器的数学原理 1.1.4 SVM核函数&#xff08;构建非线性分类器&#xff09; 及控制点的选择 1.1.5 构建自己的SVM 1.2 softmax分类器 1.3 soft…

06-07-08 - 突破512字节的限制

---- 整理自狄泰软件唐佐林老师课程 1. 突破限制的准备工作 辅助函数 字符串打印软盘读取内存比较根目录区查找 1.1 字符串打印 问题&#xff1a; 主引导程序中如何进行字符串的打印&#xff1f; 1.1.1 BIOS中的字符串打印 指定打印参数&#xff08;AX 0x1301&#xff0…