設(shè)計(jì)模式-享元模式

享元模式是一種用于性能優(yōu)化的模式,享元模式的核心是運(yùn)用共享技術(shù)來(lái)有效支持大量細(xì)粒度的對(duì)象。
如果系統(tǒng)中創(chuàng)建了大量類(lèi)似的對(duì)象而導(dǎo)致內(nèi)存占用過(guò)高,享元模式就非常有用了。在JavaScript中,瀏覽器特別是移動(dòng)端分配的內(nèi)存并不算多,如何節(jié)省內(nèi)存就成了一件非常有意義的事情。
為了讓我們能更好的理解享元模式,下面先說(shuō)一個(gè)例子。

享元模式案例

假設(shè)有個(gè)網(wǎng)店,目前有50件男裝和50件女裝,為了推銷(xiāo)產(chǎn)品,需要找模特穿上衣服,進(jìn)行拍攝圖片。在不適用享元模式的情況下,實(shí)現(xiàn)如下:

const Model = function (sex, wear) {
  this.sex = sex
  this.wear = wear
}

Model.prototype.takePhoto = function () {
  console.log(`sex=${this.sex} wear=${this.wear}`)
}

for (let i = 1; i <= 50; i++) {
  let maleModel = new Model('male', `wear${i}`)
  maleModel.takePhoto()
  let femaleModel = new Model('female', `wear${i}`)
  femaleModel.takePhoto()
}

要得到一張照片,每次需要生成100個(gè)對(duì)象,如果將來(lái)有10000種衣服,那這個(gè)程序有可能因此而奔潰。
接下來(lái)我們來(lái)改造下上面的代碼:

const Model = function(sex) {
  this.sex = sex
}

Model.prototype.takePhoto = function () {
  console.log(`sex=${this.sex} wear=${this.wear}`)
}

const maleModel = new Model('male')
const femaleModel = new Model('female')

for (let i = 1; i <= 50; i++) {
  maleModel.wear = `wear${i}`
  maleModel.takePhoto()
  femaleModel.wear = `wear${i}`
  femaleModel.takePhoto()
}

可以看到,改性之后的代碼,只需要兩個(gè)對(duì)象便完成了同樣的功能。上面的代碼便是享元模式的雛形。

內(nèi)部狀態(tài)與外部狀態(tài)

享元模式要求將對(duì)象屬性劃分為內(nèi)部狀態(tài)和外部狀態(tài)。
享元模式的目標(biāo)是盡量減少共享對(duì)象的數(shù)量。
關(guān)于如何劃分內(nèi)部狀態(tài)和外部狀態(tài),下面是幾條大致的規(guī)則:

  • 內(nèi)部狀態(tài)存儲(chǔ)于對(duì)象內(nèi)部
  • 內(nèi)部狀態(tài)可以被一些對(duì)象共享
  • 內(nèi)部狀態(tài)獨(dú)立與具體的場(chǎng)景,通常不會(huì)改變
  • 外部狀態(tài)取決于具體的場(chǎng)景,并根據(jù)場(chǎng)景而變化,外部狀態(tài)不能被共享

這樣指定內(nèi)部狀態(tài)相同的對(duì)象都指定為同一個(gè)共享的對(duì)象。而外部狀態(tài)可以從對(duì)象身上剝離出來(lái),并存儲(chǔ)在外部。

享元模式的應(yīng)用

跳轉(zhuǎn)頁(yè)面在前端開(kāi)發(fā)過(guò)程中,是最常見(jiàn)的一種操作。在頁(yè)面跳轉(zhuǎn)的時(shí)候加上一些額外的操作,也是常見(jiàn)的。下面是使用享元模式實(shí)現(xiàn)的應(yīng)用跳轉(zhuǎn):

function setExternalState (...args) {
  sessionStorage.setItem('state', 1)
  alert(sessionStorage.getItem('state') + args[0])
}

function Page (urls) {
  this.urls = {
    baidu: 'https://www.baidu.com',
    taobao: 'https://www.taobao.com',
    jianshu: 'http://m.itdecent.cn',
    ...urls
  }
}

Page.prototype.jumpUrl = function (key, fn, ...args) {
  fn && fn.apply(null, args)
  const url = this.urls[key]
  location.href = url
}
window.onload = () => {
  const page = new Page()
  page.jumpUrl('baidu', setExternalState, 'haha')
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是享元模式 模式的結(jié)構(gòu) 典型代碼 代碼示例 單純享元模式和復(fù)合享元模式 模式擴(kuò)展...
    w1992wishes閱讀 1,621評(píng)論 0 6
  • 定義 Flyweight在拳擊比賽中指最輕量級(jí),即“蠅量級(jí)”或“雨量級(jí)”。這里選擇使用“享元模式”的意譯,是因?yàn)檫@...
    步積閱讀 1,996評(píng)論 0 2
  • 享元模式(Flyweight Pattern):運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度對(duì)象的復(fù)用。系統(tǒng)只使用少量的對(duì)象,...
    breezedancer閱讀 1,965評(píng)論 2 51
  • 一.概述 享元模式(Flyweight Pattern) ,運(yùn)用共享技術(shù)有效的支持大量的細(xì)粒度對(duì)象。換句話(huà)說(shuō),使用...
    BrightLoong閱讀 1,393評(píng)論 0 2
  • 寶寶,你出生前,媽媽一直擔(dān)心自己會(huì)不會(huì)出現(xiàn)產(chǎn)后抑郁癥,現(xiàn)在看來(lái)是我多慮了。盡管生孩子是那么的痛,出生后有操不完的心...
    四月Apr閱讀 449評(píng)論 0 0

友情鏈接更多精彩內(nèi)容