javascript设计模式 ? 享元模式原理与用法实例分析


Posted in Javascript onApril 15, 2020

本文实例讲述了javascript设计模式 ? 享元模式原理与用法。分享给大家供大家参考,具体如下:

介绍:在我们日常开发中需要创建很多对象,虽然垃圾回收机制能帮我们进行回收,但是在一些需要重复创建对象的场景下,就需要有一种机制来进行优化,提高系统资源的利用率。

享元模式就是解决这类问题,主要目的是减少创建对象的数量。享元模式提倡重用现有同类对象,如未找到匹配的对象则创建新对象

定义:运用共享技术有效的支持大量细粒度对象的复用。系统只适用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度的对象,因此他又称为轻量级模式,是一种对象结构型模式。

场景:我们以创建圆形对象为例,通过两个例子来对比享元模式的效果。

示例:

var redCricle = new Circle('red');
redCricle.setAttr(10,10,10);
redCricle.draw();
 
var redCricle1 = new Circle('red');
redCricle1.setAttr(1,1,100);
redCricle1.draw();
 
var redCricle2 = new Circle('red');
redCricle2.setAttr(5,5,50);
redCricle2.draw();
 
var blueCricle = new Circle('blue');
blueCricle.setAttr(1,1,50);
blueCricle.draw();
 
var blueCricle1 = new Circle('blue');
blueCricle1.setAttr(12,12,50);
blueCricle1.draw();
 
var blueCricle2 = new Circle('blue');
blueCricle2.setAttr(2,12,20);
blueCricle2.draw();
// 创建了一个对象
// 画圆: 颜色:red x:10 y:10 radius:10
// 创建了一个对象
// 画圆: 颜色:red x:1 y:1 radius:100
// 创建了一个对象
// 画圆: 颜色:red x:5 y:5 radius:50
// 创建了一个对象
// 画圆: 颜色:blue x:1 y:1 radius:50
// 创建了一个对象
// 画圆: 颜色:blue x:12 y:12 radius:50
// 创建了一个对象
// 画圆: 颜色:blue x:2 y:12 radius:20

这种情况下每次使用都需要实例化一次Circle对象,对系统资源来说是一种浪费。

观察下不难发现,除了第一次需要实例化,其余的可以基于实例继续修改。

我们修改下:

var Circle = function(color){
  console.log('创建了一个对象');
  this.color = color;
  this.x;
  this.y;
  this.radius;
 
  this.setAttr = function(x, y, radius){
    this.x = x;
    this.y = y;
    this.radius = radius;
  }
  this.draw = function(){
    console.log('画圆: 颜色:' + this.color + ' x:' + this.x + ' y:' + this.y + ' radius:' + this.radius)
  }
}
 
var ShapeFactory = function(){
  this.circleMap = {};
  this.getCircle = function(color){
    var circle = this.circleMap[color];
    if(!circle){
      circle = new Circle(color);
      this.circleMap[color] = circle;
    }
    return circle;
  }
}
var factory = new ShapeFactory();
 
var redCricle = factory.getCircle('red');
redCricle.setAttr(10,10,10);
redCricle.draw();
 
var redCricle1 = factory.getCircle('red');
redCricle1.setAttr(1,1,100);
redCricle1.draw();
 
var redCricle2 = factory.getCircle('red');
redCricle2.setAttr(5,5,50);
redCricle2.draw();
 
var blueCricle = factory.getCircle('blue'); 
blueCricle.setAttr(1,1,50);
blueCricle.draw();
 
var blueCricle1 = factory.getCircle('blue');
blueCricle1.setAttr(12,12,50);
blueCricle1.draw();
 
var blueCricle2 = factory.getCircle('blue');
blueCricle2.setAttr(2,12,20);
blueCricle2.draw();
 
// 创建了一个对象
// 画圆: 颜色:red x:10 y:10 radius:10
// 画圆: 颜色:red x:1 y:1 radius:100
// 画圆: 颜色:red x:5 y:5 radius:50
// 创建了一个对象
// 画圆: 颜色:blue x:1 y:1 radius:50
// 画圆: 颜色:blue x:12 y:12 radius:50
// 画圆: 颜色:blue x:2 y:12 radius:20

我们通过一个工厂来动态创建Circle对象,将实例进行保存,保存的位置称之为享元池。第二次创建时,直接使用已有的结果。节约了系统资源

享元模式总结:

优点:
* 大大减少对象的创建,降低系统内存使用,使效率提高。
* 享元模式外部状态独立,不会影响其内部状态,使得享元对象可以在不同环境被共享。

缺点:
* 提高了系统复杂度,且需要相同的属性,否则会造成系统混乱

适用场景:
* 一个系统有大量相同或相似的对象,造成内存大量耗费。
* 对象大部分状态都可以外部化
* 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源。因此使用时要衡量。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
读jQuery之十四 (触发事件核心方法)
Aug 23 Javascript
jQuery根据纬度经度查看地图处理程序
May 08 Javascript
js实现iframe框架取值的方法(兼容IE,firefox,chrome等)
Nov 26 Javascript
学习javascript面向对象 理解javascript原型和原型链
Jan 04 Javascript
jQuery绑定事件的几种实现方式
May 09 Javascript
javascript设计模式之模块模式学习笔记
Feb 15 Javascript
JS实现的五级联动菜单效果完整实例
Feb 23 Javascript
javascript 取小数点后几位几种方法总结
Aug 02 Javascript
微信小程序实现图片上传功能
May 28 Javascript
使用Vue做一个简单的todo应用的三种方式的示例代码
Oct 20 Javascript
bootstrap中的导航条实例代码详解
May 20 Javascript
vue常用高阶函数及综合实例
Feb 25 Vue.js
javascript设计模式 ? 外观模式原理与用法实例分析
Apr 15 #Javascript
写给新手同学的vuex快速上手指北小结
Apr 14 #Javascript
vue-cli设置publicPath小记
Apr 14 #Javascript
vue 实现用户登录方式的切换功能
Apr 14 #Javascript
react 不用插件实现数字滚动的效果示例
Apr 14 #Javascript
详解在Vue.js编写更好的v-for循环的6种技巧
Apr 14 #Javascript
编写一个javascript元循环求值器的方法
Apr 14 #Javascript
You might like
Gregarius中文日期格式问题解决办法
2008/04/22 PHP
php中判断文件存在是用file_exists还是is_file的整理
2012/09/12 PHP
php实现信用卡校验位算法THE LUHN MOD-10示例
2014/05/07 PHP
PHP实现重载的常用方法实例详解
2017/10/18 PHP
PHP实现负载均衡的加权轮询方法分析
2018/08/22 PHP
laravel dingo API返回自定义错误信息的实例
2019/09/29 PHP
PHP实现Markdown文章上传到七牛图床的实例内容
2020/02/11 PHP
总结一些js自定义的函数
2006/08/05 Javascript
$()JS小技巧
2007/07/21 Javascript
Bootstrap入门书籍之(零)Bootstrap简介
2016/02/17 Javascript
基于jquery实现的银行卡号每隔4位自动插入空格的实现代码
2016/11/22 Javascript
JS简单实现点击跳转登陆邮箱功能的方法
2017/10/31 Javascript
React Native悬浮按钮组件的示例代码
2018/04/05 Javascript
js中的this的指向问题详解
2019/08/29 Javascript
Ant Design Vue 添加区分中英文的长度校验功能
2020/01/21 Javascript
javascript History对象原理解析
2020/02/17 Javascript
[54:33]2018DOTA2亚洲邀请赛小组赛 A组加赛 Liquid vs Optic
2018/04/03 DOTA
Python高级应用实例对比:高效计算大文件中的最长行的长度
2014/06/08 Python
Python实现遍历windows所有窗口并输出窗口标题的方法
2015/03/13 Python
在Python中处理XML的教程
2015/04/29 Python
解决Python的str强转int时遇到的问题
2018/04/09 Python
Python3实现的旋转矩阵图像算法示例
2019/04/03 Python
python将类似json的数据存储到MySQL中的实例
2019/07/12 Python
anaconda中更改python版本的方法步骤
2019/07/14 Python
详解Django 时间与时区设置问题
2019/07/23 Python
python2.7实现复制大量文件及文件夹资料
2019/08/31 Python
Python代码执行时间测量模块timeit用法解析
2020/07/01 Python
新西兰床上用品和家居用品购物网站:Adairs
2018/04/27 全球购物
英国美术用品购物网站:Cass Art
2019/10/08 全球购物
澳大利亚头发和美容产品购物网站:OZ Hair & Beauty
2020/03/27 全球购物
电子信息专业自荐书
2014/02/04 职场文书
2014年两会学习心得范例
2014/03/17 职场文书
工作失职检讨书500字
2014/10/17 职场文书
2014年党员发展工作总结
2014/12/02 职场文书
公司前台接待岗位职责
2015/04/03 职场文书
python for循环赋值问题
2021/06/03 Python