欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

學(xué)習(xí)JavaScript設(shè)計(jì)模式之享元模式

 更新時(shí)間:2016年01月18日 17:14:04   作者:奮飛  
這篇文章主要為大家介紹了JavaScript設(shè)計(jì)模式中的享元模式,對JavaScript設(shè)計(jì)模式感興趣的小伙伴們可以參考一下

一、定義

享元(flyweight)模式是一種用于性能優(yōu)化的模式,核心是運(yùn)用共享技術(shù)來有效支持大量細(xì)刻度的對象。
在JavaScript中,瀏覽器特別是移動端的瀏覽器分配的內(nèi)存并不算多,如何節(jié)省內(nèi)存就成了一個(gè)非常有意義的事情。
享元模式是一種用時(shí)間換空間的優(yōu)化模式

  • 內(nèi)衣工廠有100種男士內(nèi)衣、100中女士內(nèi)衣,要求給每種內(nèi)衣拍照。如果不使用享元模式則需要200個(gè)塑料模特;使用享元模式,只需要男女各1個(gè)模特。

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

(1)程序中使用大量的相似對象,造成很大的內(nèi)存開銷
(2)對象的大多數(shù)狀態(tài)都可以變?yōu)橥獠繝顟B(tài),剝離外部狀態(tài)之后,可以用相對較少的共享對象取代大量對象

三、如何應(yīng)用享元模式?

第一種是應(yīng)用在數(shù)據(jù)層上,主要是應(yīng)用在內(nèi)存里大量相似的對象上;
第二種是應(yīng)用在DOM層上,享元可以用在中央事件管理器上用來避免給父容器里的每個(gè)子元素都附加事件句柄。

享元模式要求將對象的屬性分為內(nèi)部狀態(tài)外部狀態(tài)
內(nèi)部狀態(tài)獨(dú)立于具體的場景,通常不會改變,可以被一些對象共享;
外部狀態(tài)取決于具體的場景,并根據(jù)場景而變化,外部狀態(tài)不能被共享。

享元模式中常出現(xiàn)工廠模式,F(xiàn)lyweight的內(nèi)部狀態(tài)是用來共享的,F(xiàn)lyweight factory負(fù)責(zé)維護(hù)一個(gè)Flyweight pool(模式池)來存放內(nèi)部狀態(tài)的對象。

缺點(diǎn):對象數(shù)量少的情況,可能會增大系統(tǒng)的開銷,實(shí)現(xiàn)的復(fù)雜度較大!

四、示例:文件上傳

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

/* 刪除文件(內(nèi)部狀態(tài)) */
Upload.prototype.delFile = function(id) {
  uploadManger.setExternalState(id, this);  // 把當(dāng)前id對應(yīng)的外部狀態(tài)都組裝到共享對象中
  // 大于3000k提示
  if(this.fileSize < 3000) {
    return this.dom.parentNode.removeChild(this.dom);
  }
  if(window.confirm("確定要刪除文件嗎?" + this.fileName)) {
    return this.dom.parentNode.removeChild(this.dom);
  }
}

/** 工廠對象實(shí)例化 
 * 如果某種內(nèi)部狀態(tài)的共享對象已經(jīng)被創(chuàng)建過,那么直接返回這個(gè)對象
 * 否則,創(chuàng)建一個(gè)新的對象
 */
var UploadFactory = (function() {
  var createdFlyWeightObjs = {};
  return {
    create: function(uploadType) {
      if(createdFlyWeightObjs[uploadType]) {
        return createdFlyWeightObjs[uploadType];
      }
      return createdFlyWeightObjs[uploadType] = new Upload(uploadType);
    }
  };
})();

/* 管理器封裝外部狀態(tài) */
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];
      }
    }
  };
})();

/*觸發(fā)上傳動作*/
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
  }
]);

五、補(bǔ)充

(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)對象池,也是一種性能優(yōu)化方案,其跟享元模式有一些相似之處,但沒有分離內(nèi)部狀態(tài)和外部狀態(tài)的過程。

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);
    }
  };
}

希望本文所述對大家學(xué)習(xí)javascript程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • JavaScript實(shí)現(xiàn)移動端簽字功能

    JavaScript實(shí)現(xiàn)移動端簽字功能

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)移動端簽字功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • @ResponseBody 和 @RequestBody 注解的區(qū)別

    @ResponseBody 和 @RequestBody 注解的區(qū)別

    這篇文章主要介紹了@ResponseBody 和 @RequestBody 注解的區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Echarts折線圖設(shè)置線條顏色及線條以下代碼示例

    Echarts折線圖設(shè)置線條顏色及線條以下代碼示例

    最近項(xiàng)目需要,一直在使用Echarts視圖,現(xiàn)在遇到一個(gè)要修改echarts折線圖顏色的需求,下面這篇文章主要給大家介紹了關(guān)于Echarts折線圖設(shè)置線條顏色及線條以下區(qū)域漸變顏色的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • JavaScript 刪除或抽取字符串指定字符的方法(極為常用)

    JavaScript 刪除或抽取字符串指定字符的方法(極為常用)

    這篇文章主要給大家分享了極為常用的JavaScript 刪除或抽取字符串指定字符的所有方法,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2021-12-12
  • 深入淺析JavaScript中的scrollTop

    深入淺析JavaScript中的scrollTop

    這篇文章主要介紹了深入淺析JavaScript中的scrollTop的相關(guān)資料,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • JS中的phototype詳解

    JS中的phototype詳解

    本文主要介紹了JS中phototype的相關(guān)知識。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • 微信小程序bindtap事件與冒泡阻止詳解

    微信小程序bindtap事件與冒泡阻止詳解

    這篇文章主要介紹了小程序bindtap事件與冒泡阻止詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • JS實(shí)現(xiàn)拖動模態(tài)框案例

    JS實(shí)現(xiàn)拖動模態(tài)框案例

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)拖動模態(tài)框案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • JS實(shí)現(xiàn)點(diǎn)擊復(fù)選框變更DIV顯示狀態(tài)的示例代碼

    JS實(shí)現(xiàn)點(diǎn)擊復(fù)選框變更DIV顯示狀態(tài)的示例代碼

    下面小編就為大家分享一篇JS實(shí)現(xiàn)點(diǎn)擊復(fù)選框變更DIV顯示狀態(tài)的示例代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • JavaScript字符串處理常見操作方法小結(jié)

    JavaScript字符串處理常見操作方法小結(jié)

    這篇文章主要介紹了JavaScript字符串處理常見操作方法,結(jié)合實(shí)例形式分析了JavaScript字符串操作常見的轉(zhuǎn)換、截取、分割、獲取等相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-11-11

最新評論