国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

學習JavaScript設計模式之享元模式

2019-11-20 10:46:31
字體:
來源:轉載
供稿:網友

一、定義

享元(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程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 凤城市| 永兴县| 涪陵区| 洪湖市| 祁连县| 保定市| 九龙坡区| 交口县| 太原市| 铜梁县| 沁水县| 油尖旺区| 元氏县| 济宁市| 新巴尔虎左旗| 靖安县| 清镇市| 太康县| 瑞金市| 吉林市| 荃湾区| 和田市| 株洲县| 土默特右旗| 滦南县| 漳州市| 陵川县| 隆尧县| 响水县| 吉首市| 德昌县| 永登县| 台南市| 广宁县| 上犹县| 盈江县| 延川县| 武威市| 柯坪县| 安达市| 郎溪县|