学习JavaScript设计模式之享元模式

一、定义

享元(flyweight)模式是一种用于性能优化的模式,核心是运用共享技术来有效支持大量细刻度的对象。
在JavaScript中,浏览器特别是移动端的浏览器分配的内存并不算多,如何节省内存就成了一个非常有意义的事情。
享元模式是一种用时间换空间的优化模式

  • 内衣工厂有100种男士内衣、100中女士内衣,要求给每种内衣拍照。如果不使用享元模式则需要200个塑料模特;使用享元模式,只需要男女各1个模特。

二、什么场景下使用享元模式?

(1)程序中使用大量的相似对象,造成很大的内存开销
(2)对象的大多数状态都可以变为外部状态,剥离外部状态之后,可以用相对较少的共享对象取代大量对象

三、如何应用享元模式?

第一种是应用在数据层上,主要是应用在内存里大量相似的对象上;
第二种是应用在DOM层上,享元可以用在中央事件管理器上用来避免给父容器里的每个子元素都附加事件句柄。

享元模式要求将对象的属性分为内部状态外部状态
内部状态独立于具体的场景,通常不会改变,可以被一些对象共享;
外部状态取决于具体的场景,并根据场景而变化,外部状态不能被共享。

享元模式中常出现工厂模式,Flyweight的内部状态是用来共享的,Flyweight factory负责维护一个Flyweight pool(模式池)来存放内部状态的对象。

缺点:对象数量少的情况,可能会增大系统的开销,实现的复杂度较大!

四、示例:文件上传

var Upload = function(uploadType) {
  this.uploadType = uploadType;
}

/* 删除文件(内部状态) */
Upload.prototype.delFile = function(id) {
  uploadManger.setExternalState(id, this);  // 把当前id对应的外部状态都组装到共享对象中
  // 大于3000k提示
  if(this.fileSize < 3000) {
    return this.dom.parentNode.removeChild(this.dom);
  }
  if(window.confirm("确定要删除文件吗?" + this.fileName)) {
    return this.dom.parentNode.removeChild(this.dom);
  }
}

/** 工厂对象实例化
 * 如果某种内部状态的共享对象已经被创建过,那么直接返回这个对象
 * 否则,创建一个新的对象
 */
var UploadFactory = (function() {
  var createdFlyWeightObjs = {};
  return {
    create: function(uploadType) {
      if(createdFlyWeightObjs[uploadType]) {
        return createdFlyWeightObjs[uploadType];
      }
      return createdFlyWeightObjs[uploadType] = new Upload(uploadType);
    }
  };
})();

/* 管理器封装外部状态 */
var uploadManger = (function() {
  var uploadDatabase = {};

  return {
    add: function(id, uploadType, fileName, fileSize) {
      var flyWeightObj = UploadFactory.create(uploadType);
      var dom = document.createElement('div');
      dom.innerHTML = "<span>文件名称:" + fileName + ",文件大小:" + fileSize +"</span>"
             + "<button class='delFile'>删除</button>";

      dom.querySelector(".delFile").onclick = function() {
        flyWeightObj.delFile(id);
      };
      document.body.appendChild(dom);

      uploadDatabase[id] = {
        fileName: fileName,
        fileSize: fileSize,
        dom: dom
      };

      return flyWeightObj;
    },
    setExternalState: function(id, flyWeightObj) {
      var uploadData = uploadDatabase[id];
      for(var i in uploadData) {
        // 直接改变形参(新思路!!)
        flyWeightObj[i] = uploadData[i];
      }
    }
  };
})();

/*触发上传动作*/
var id = 0;
window.startUpload = function(uploadType, files) {
  for(var i=0,file; file = files[i++];) {
    var uploadObj = uploadManger.add(++id, uploadType, file.fileName, file.fileSize);
  }
};

/* 测试 */
startUpload("plugin", [
  {
    fileName: '1.txt',
    fileSize: 1000
  },{
    fileName: '2.txt',
    fileSize: 3000
  },{
    fileName: '3.txt',
    fileSize: 5000
  }
]);
startUpload("flash", [
  {
    fileName: '4.txt',
    fileSize: 1000
  },{
    fileName: '5.txt',
    fileSize: 3000
  },{
    fileName: '6.txt',
    fileSize: 5000
  }
]);

五、补充

(1)直接改变形参Demo

function f1() {
  var obj = {a: 1};
  f2(obj);
  console.log(obj);  // {a: 1, b: 2}
}
function f2(obj) {
  obj.b = 2;
}
f1();

(2)对象池,也是一种性能优化方案,其跟享元模式有一些相似之处,但没有分离内部状态和外部状态的过程。

var objectPoolFactory = function(createObjFn) {
  var objectPool = [];
  return {
    create: function() {
      var obj = objectPool.lenght === 0 ? createObjFn.apply(this, arguments) : objectPool.shift();
      return obj;
    },
    recover: function() {
      objectPool.push(obj);
    }
  };
}

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

(0)

相关推荐

  • 总结JavaScript设计模式编程中的享元模式使用

    享元模式不同于一般的设计模式,它主要用来优化程序的性能,它最适合解决大量类似的对象而产生的性能问题.享元模式通过分析应用程序的对象,将其解析为内在数据和外在数据,减少对象的数量,从而提高应用程序的性能. 基本知识 享元模式通过共享大量的细粒度的对象,减少对象的数量,从而减少对象的内存,提高应用程序的性能.其基本思想就是分解现有类似对象的组成,将其展开为可以共享的内在数据和不可共享的外在数据,我们称内在数据的对象为享元对象.通常还需要一个工厂类来维护内在数据. 在JS中,享元模式主要有下面几个角色

  • js设计模式之结构型享元模式详解

    运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销. 享元模式主要是对其数据.方法共享分离,将数据和方法分成内部数据.内部方法和外部数据.外部方法.内部方法与内部数据指的是相似或共有的数据和方法,所以将其提取出来减少开销. var Flyweight = function() { // 已创建的元素 var created = []; // 创建一个新闻包装容器 function create() { var dom = document.createElement(

  • 轻松掌握JavaScript享元模式

    在JavaScript中,浏览器特别是移动端的浏览器分配的内存很有限,如何节省内存就成了一件非常有意义的事情.节省内存的一个有效方法是减少对象的数量. 享元模式(Flyweight),运行共享技术有效地支持大量细粒度的对象,避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类). 享元模式可以避免大量非常相似类的开销,在程序设计中,有时需要生产大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数以外,开销基本相同的话,就可以大幅度较少需要实例化的类的数量.如果能把那些参

  • JS实现简单的图书馆享元模式实例

    本文实例讲述了JS实现简单的图书馆享元模式.分享给大家供大家参考.具体如下: <!DOCTYPE html> <html> <head> <title>享员模式</title> </head> <body> <script> /* *flyweight 享员模式 */ //例子是一个图书馆存书借书 ->_-> var Book = function(id, title, author, genre,

  • 深入理解JavaScript系列(37):设计模式之享元模式详解

    介绍 享元模式(Flyweight),运行共享技术有效地支持大量细粒度的对象,避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类). 享元模式可以避免大量非常相似类的开销,在程序设计中,有时需要生产大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数以外,开销基本相同的 话,就可以大幅度较少需要实例化的类的数量.如果能把那些参数移动到类实例的外面,在方法调用的时候将他们传递进来,就可以通过共享大幅度第减少单个实例 的数目. 那么如果在JavaScript中应用享元模式

  • 学习JavaScript设计模式之享元模式

    一.定义 享元(flyweight)模式是一种用于性能优化的模式,核心是运用共享技术来有效支持大量细刻度的对象. 在JavaScript中,浏览器特别是移动端的浏览器分配的内存并不算多,如何节省内存就成了一个非常有意义的事情. 享元模式是一种用时间换空间的优化模式 内衣工厂有100种男士内衣.100中女士内衣,要求给每种内衣拍照.如果不使用享元模式则需要200个塑料模特:使用享元模式,只需要男女各1个模特. 二.什么场景下使用享元模式? (1)程序中使用大量的相似对象,造成很大的内存开销 (2)

  • JavaScript设计模式之享元模式实例详解

    本文实例讲述了JavaScript设计模式之享元模式.分享给大家供大家参考,具体如下: 通过两个例子的对比来凸显享元模式的特点:享元模式是一个为了提高性能(空间复杂度)的设计模式,享元模式可以避免大量非常相似类的开销. 第一实例,没有使用享元模式,计算所花费的时间和空间使用程度. 要求为:有一个城市要进行汽车的登记 (1)汽车类 /** * 制造商 * 型号 * 拥有者 * 车牌号码 * 最近一次登记日期 */ var Car = function(make,model,year,owner,t

  • javascript 设计模式之享元模式原理与应用详解

    本文实例讲述了javascript 设计模式之享元模式.分享给大家供大家参考,具体如下: 享元模式说明 定义:用于解决一个系统大量细粒度对象的共享问题: 关健词:分离跟共享: 说明: 享元模式分单纯(共享)享元模式,以及组合(不共享)享元模式,有共享跟不共享之分:单纯享元模式,只包含共享的状态,可共享状态是不可变,不可修改的,这是享元的内部状态:当然有外部状态就有外部状态,外部状态是可变的,不被共享,这个外部状态由客户端来管理,是可变化的:外部状态与内部状态是独立分开的,外部状态一般作为参数传入

  • javascript设计模式之享元模式

    目录 一. 认识享元模式 二. 代码具体实现 1. 不使用享元模式实现上述案例 2. 使用享元模式重构上述代码 3. 享元模式的状态 三. 享元模式实际应用 扩展:再谈内部状态和外部状态 四. 对象池 五. 总结 一. 认识享元模式 享元模式:是一种用于性能优化的模式,其核心是运用共享技术来有效支持大量细粒度的对象. 通俗点来讲就是找出事物很多属性种属性分类最少的一种,利用属性值的个数来分类.比如说有这么一个例子,假如一个工厂需要 20 个男性模特和 20 个女性模特需要穿上 40 件新款衣服拍

  • Java设计模式之享元模式实例详解

    本文实例讲述了Java设计模式之享元模式.分享给大家供大家参考,具体如下: 解释一下概念:也就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象.比如说一个文本系统,每个字母定一个对象,那么大小写字母一共就是52个,那么就要定义52个对象.如果有一个1M的文本,那么字母是何其的多,如果每个字母都定义一个对象那么内存早就爆了.那么如果要是每个字母都共享一个对象,那么就大大节约了资源. 在Flyweight模式中,由于要产生各种各样的对象,所以在Flyweigh

  • Java设计模式之享元模式

    本文介绍了Java设计模式之享元模式,供大家参考,具体内容如下 1.关于享元模式 享元模式有点类似于单例模式,都是只生成一个对象被共享使用.享元模式主要目的就是让多个对象实现共享,减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗. 2.享元模式结构图 因为享元模式结构比较复杂,一般结合工厂模式一起使用,在它的结构图中包含了一个享元工厂类. 在享元模式结构图中包含如下几个角色: Flyweight(抽象享元类):通常是一个接口或抽象类,

  • .Net结构型设计模式之享元模式(Flyweight)

    目录 一.动机(Motivate) 二.意图(Intent) 三.结构图(Structure) 四.模式的组成 五.享元模式的具体代码实现 六.享元模式的实现要点: 1.享元模式的优点 2.享元模式的缺点 3.在下面所有条件都满足时,可以考虑使用享元模式: 七..NET 中享元模式的实现 一.动机(Motivate) 在软件系统中,采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同时,让外部客户程序

  • Python设计模式之享元模式原理与用法实例分析

    本文实例讲述了Python设计模式之享元模式原理与用法.分享给大家供大家参考,具体如下: 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象. 下面是一个享元模式的demo: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Andy' """ 大话设计模式 设计模式--享元模式 享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象 对一个

  • 浅谈JAVA设计模式之享元模式

    享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象.我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式.由于只有 5 种可用的颜色,所以 color 属性被用来检查现有的 Circle 对象. 介绍 意图: 运用共享技术有效地支持大量细粒度的对象. 主要解决: 在有大量

随机推荐