中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

織夢(mèng)網(wǎng)站可以微信登錄嗎友情鏈接什么意思

織夢(mèng)網(wǎng)站可以微信登錄嗎,友情鏈接什么意思,做電影網(wǎng)站代理合法么,制作相冊(cè)視頻參考資料 曾探《JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》;「設(shè)計(jì)模式 JavaScript 描述」享元模式設(shè)計(jì)模式之享元模式Javascript 設(shè)計(jì)模式 - 享元模式 定義 享元模式的英文叫:Flyweight Design Pattern。享元設(shè)計(jì)模式是用于性能優(yōu)化的模式,這種設(shè)計(jì)…

參考資料

  • 曾探《JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》;
  • 「設(shè)計(jì)模式 JavaScript 描述」享元模式
  • 設(shè)計(jì)模式之享元模式
  • Javascript 設(shè)計(jì)模式 - 享元模式

定義

享元模式的英文叫:Flyweight Design Pattern。享元設(shè)計(jì)模式是用于性能優(yōu)化的模式,這種設(shè)計(jì)模式的核心在于可以共享技術(shù)并支持對(duì)大量細(xì)分過(guò)后的對(duì)象進(jìn)行調(diào)整,如果系統(tǒng)中因?yàn)閯?chuàng)建大量類似的對(duì)象而導(dǎo)致內(nèi)存占用過(guò)高,享元設(shè)計(jì)模式在其中就會(huì)起到非常重要的作用,因?yàn)樗梢允蛊錅p少重復(fù)創(chuàng)建相同類似的實(shí)例對(duì)象。在JavaScript中瀏覽器特別是移動(dòng)端的瀏覽器部分所能夠使用的內(nèi)存并不是很多,所以在其中節(jié)省內(nèi)存就變得至關(guān)重要。

享元模式屬于結(jié)構(gòu)型模式,它提供了減少對(duì)象數(shù)量從而改善應(yīng)用所需的對(duì)象結(jié)構(gòu)的方式。

享元模式(Flyweight Pattern)主要用于減少創(chuàng)建對(duì)象的數(shù)量,以減少內(nèi)存占用和提高性能。

就是分享之意,指一物被眾人共享,而這也正是該模式的終旨所在,意為單元,蠅量級(jí)的個(gè)體,該模式的核心就是使用共享技術(shù)來(lái)有效的支持大量的細(xì)粒度對(duì)象。

使用場(chǎng)景:

  • 數(shù)據(jù)庫(kù)連接池;
  • 線程池;
  • String常量池;

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

享元模式要求將對(duì)象的屬性劃分為內(nèi)部狀態(tài)外部狀態(tài)(狀態(tài)在這里通常指屬性)。享元模式的目標(biāo)是盡量減少共享對(duì)象的數(shù)量,那么如何劃分內(nèi)部狀態(tài)和外部狀態(tài)呢?

  • 內(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ǔ)存在外部。

剝離了外部狀態(tài)的對(duì)象成為共享對(duì)象,外部狀態(tài)在必要時(shí)被傳入共享對(duì)象來(lái)組裝成一個(gè)完整 的對(duì)象。雖然組裝外部狀態(tài)成為一個(gè)完整對(duì)象的過(guò)程需要花費(fèi)一定的時(shí)間,但卻可以大大減少系 統(tǒng)中的對(duì)象數(shù)量,相比之下,這點(diǎn)時(shí)間或許是微不足道的。因此,享元模式是一種用時(shí)間換空間的優(yōu)化模式。

使用享元模式的關(guān)鍵是如何區(qū)別內(nèi)部狀態(tài)外部狀態(tài)。

舉例說(shuō)明-下象棋

我們還是通過(guò)網(wǎng)絡(luò)上開(kāi)房間下象棋的經(jīng)典案例來(lái)說(shuō)明享元設(shè)計(jì)模式。一個(gè)象棋游戲平臺(tái)肯定有很多的房間,每個(gè)房間都有一盤棋,每盤棋上有32顆棋子,就有32個(gè)對(duì)象,但是每個(gè)房間里的【將】的屬性有很多都是相同的,比如名字、顏色等,而且它們?cè)诟鱾€(gè)房間的棋盤中都是不會(huì)發(fā)生變化的,唯一不同的就是所在的位置不一樣。所以相同的屬性就可以抽出來(lái)作為共享單元。

看例子:

享元類,即棋子公共的屬性

public class ShareChessAttr {private Integer id;private String name;private String color;public ShareChessAttr(Integer id, String name, String color) {this.id = id;this.name = name;this.color = color;}
}

定義一個(gè)工廠去獲取對(duì)應(yīng)棋子的享元

public class ShareChessAttrFactory {public static final HashMap<Integer, ShareChessAttr> shareChessAttrMap = new HashMap();static {shareChessAttrMap.put(1, new ShareChessAttr(1, "將", "紅"));shareChessAttrMap.put(2, new ShareChessAttr(2, "帥", "黑"));shareChessAttrMap.put(3, new ShareChessAttr(3, "車", "紅"));shareChessAttrMap.put(4, new ShareChessAttr(4, "車", "黑"));}public static ShareChessAttr getShareChessAttr(Integer i) {return shareChessAttrMap.get(i);}
}

定義棋子

public class Chess {private ShareChessAttr shareChessAttr;private Integer positionX;private Integer positionY;public Chess(ShareChessAttr shareChessAttr, Integer positionX, Integer positionY) {this.shareChessAttr = shareChessAttr;this.positionX = positionX;this.positionY = positionY;}
}

定義棋盤

public class ChessBoard {private HashMap<Integer, Chess> chessOnBoard = new HashMap<Integer, Chess>();public ChessBoard() {chessOnBoard.put(1, new Chess(ShareChessAttrFactory.getShareChessAttr(1), 5, 0));chessOnBoard.put(2, new Chess(ShareChessAttrFactory.getShareChessAttr(2), 5, 0));}
}

如此每個(gè)棋盤中的棋子的id,名字和顏色都指向了同一個(gè)shareChessAttr。實(shí)現(xiàn)享元。

舉例說(shuō)明- HashMap 對(duì)象池

代碼關(guān)鍵點(diǎn):用 HashMap 對(duì)象池存儲(chǔ)這些對(duì)象。

// 享元模式,對(duì)象池緩存對(duì)象
class colorFactory {constructor(name) {this.colors = {};}create(name) {let color = this.colors[name];if (color) return color;this.colors[name] = new Color(name);return this.colors[name];}
};

舉例說(shuō)明- 文件上傳

在云文件上傳模塊的開(kāi)發(fā)中,我們可以借助享元模式提升了程序的性能。下面我們就講述這個(gè)例子。

對(duì)象爆炸

在云文件上傳模塊的開(kāi)發(fā)中,可能會(huì)出現(xiàn)對(duì)象爆炸的問(wèn)題。云文件的文件上傳功能雖然可以選擇依照隊(duì)列,一個(gè)一個(gè)地排隊(duì)上傳,但也支持同時(shí)選擇 2000 個(gè)文件。每一個(gè)文件都對(duì)應(yīng)著一個(gè) JavaScript 上傳對(duì)象的創(chuàng)建,可是往程序里同時(shí) new 了 2000 個(gè) upload 對(duì)象,結(jié) 果可想而知,Chrome 中還勉強(qiáng)能夠支撐,IE 下直接進(jìn)入假死狀態(tài)。

云文件支持好幾種上傳方式,比如瀏覽器插件、Flash 和表單上傳等,為了簡(jiǎn)化例子,我們先假設(shè)只有插件和 Flash 這兩種。不論是插件上傳,還是 Flash 上傳,原理都是一樣的,當(dāng)用戶選擇了文件之后,插件和 Flash 都會(huì)通知調(diào)用 Window 下的一個(gè)全局 JavaScript 函數(shù),它的名字是 startUpload,用戶選擇的文件列表被組合成一個(gè)數(shù)組 files 塞進(jìn)該函數(shù)的參數(shù)列表里,代碼如下:

let id = 0;window.startUpload = function (uploadType, files) { // uploadType 區(qū)分是控件還是 flash for (let i = 0; i < files.length; i++) {const uploadObj = new Upload(uploadType, files[i].fileName, files[i].fileSize);uploadObj.init(id++); // 給 upload 對(duì)象設(shè)置一個(gè)唯一的 id }
};

當(dāng)用戶選擇完文件之后,startUpload 函數(shù)會(huì)遍歷 files 數(shù)組來(lái)創(chuàng)建對(duì)應(yīng)的 upload 對(duì)象。接下來(lái)定義 Upload 構(gòu)造函數(shù),它接受 3 個(gè)參數(shù),分別是插件類型、文件名文件大小。這些信息都已經(jīng)被插件組裝在 files 數(shù)組里返回,代碼如下:

const Upload = function (uploadType, fileName, fileSize) {this.uploadType = uploadType;this.fileName = fileName;this.fileSize = fileSize;this.dom = null;
};Upload.prototype.init = function (id) {const that = this;this.id = id;this.dom = document.createElement('div');this.dom.innerHTML ='<span>文件名稱:' + this.fileName + ', 文件大小: ' + this.fileSize + '</span>' +'<button class="delFile">刪除</button>';this.dom.querySelector('.delFile').onclick = function () {that.delFile();}document.body.appendChild(this.dom);
};

同樣為了簡(jiǎn)化示例,我們暫且去掉了 upload 對(duì)象的其他功能,只保留刪除文件的功能,對(duì)應(yīng) 的方法是 Upload.prototype.delFile。該方法中有一個(gè)邏輯:當(dāng)被刪除的文件小于 3000 KB 時(shí),該文件將被直接刪除。否則頁(yè)面中會(huì)彈出一個(gè)提示框,提示用戶是否確認(rèn)要?jiǎng)h除該文件,代碼如下:

Upload.prototype.delFile = function () {if (this.fileSize < 3000) {return this.dom.parentNode.removeChild(this.dom);}if (window.confirm('確定要?jiǎng)h除該文件嗎? ' + this.fileName)) {return this.dom.parentNode.removeChild(this.dom);}
};

接下來(lái)分別創(chuàng)建 3 個(gè)插件上傳對(duì)象和 3 個(gè) Flash 上傳對(duì)象:

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

當(dāng)點(diǎn)擊刪除最后一個(gè)文件時(shí),可以看到彈出了是否確認(rèn)刪除的提示,如下圖所示。

享元模式重構(gòu)文件上傳

上一節(jié)的代碼是第一版的文件上傳,在這段代碼里有多少個(gè)需要上傳的文件,就一共創(chuàng)建了多少個(gè) upload 對(duì)象,接下來(lái)我們用享元模式重構(gòu)它。

首先,我們需要確認(rèn)插件類型 uploadType 是內(nèi)部狀態(tài),那為什么單單 uploadType 是內(nèi)部狀態(tài)呢?前面講過(guò),劃分內(nèi)部狀態(tài)和外部狀態(tài)的關(guān)鍵主要有以下幾點(diǎn)。

  • 內(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)不能被共享。

在文件上傳的例子里,upload 對(duì)象必須依賴 uploadType 屬性才能工作,這是因?yàn)椴寮蟼?、Flash 上傳、表單上傳的實(shí)際工作原理有很大的區(qū)別,它們各自調(diào)用的接口也是完全不一樣的,必須在對(duì)象創(chuàng)建之初就明確它是什么類型的插件,才可以在程序的運(yùn)行過(guò)程中,讓它們分別調(diào)用各自的 startpause、cancel、del 等方法。

實(shí)際上在云文件的真實(shí)代碼中,雖然插件和 Flash 上傳對(duì)象最終創(chuàng)建自一個(gè)大的工廠類,但它們實(shí)際上根據(jù) uploadType 值的不同,分別是來(lái)自于兩個(gè)不同類的對(duì)象。(在目前的例子中,為了 簡(jiǎn)化代碼,我們把插件和 Flash 的構(gòu)造函數(shù)合并成了一個(gè)。)

一旦明確了 uploadType,無(wú)論我們使用什么方式上傳,這個(gè)上傳對(duì)象都是可以被任何文件共 用的。而 fileNamefileSize 是根據(jù)場(chǎng)景而變化的,每個(gè)文件的 fileNamefileSize 都不一樣,fileNamefileSize 沒(méi)有辦法被共享,它們只能被劃分為外部狀態(tài)。

剝離外部狀態(tài)

明確了 uploadType 作為內(nèi)部狀態(tài)之后,我們?cè)侔哑渌耐獠繝顟B(tài)從構(gòu)造函數(shù)中抽離出來(lái),Upload 構(gòu)造函數(shù)中只保留 uploadType 參數(shù):

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

Upload.prototype.init 函數(shù)也不再需要,因?yàn)?upload 對(duì)象初始化的工作被放在了 uploadManager.add 函數(shù)里面,接下來(lái)只需要定義 Upload.prototype.del 函數(shù)即可:

Upload.prototype.delFile = function (id) {uploadManager.setExternalState(id, this);  // (1) if (this.fileSize < 3000) {return this.dom.parentNode.removeChild(this.dom);}if (window.confirm('確定要?jiǎng)h除該文件嗎? ' + this.fileName)) {return this.dom.parentNode.removeChild(this.dom);}
};

在開(kāi)始刪除文件之前,需要讀取文件的實(shí)際大小,而文件的實(shí)際大小被儲(chǔ)存在外部管理器 uploadManager 中,所以在這里需要通過(guò) uploadManager.setExternalState 方法給共享對(duì)象設(shè)置正確的 fileSize,上段代碼中的(1)處表示把當(dāng)前 id 對(duì)應(yīng)的對(duì)象的外部狀態(tài)都組裝到共享對(duì)象中。

工廠進(jìn)行對(duì)象實(shí)例化

接下來(lái)定義一個(gè)工廠來(lái)創(chuàng)建 upload 對(duì)象,如果某種內(nèi)部狀態(tài)對(duì)應(yīng)的共享對(duì)象已經(jīng)被創(chuàng)建過(guò),那么直接返回這個(gè)對(duì)象,否則創(chuàng)建一個(gè)新的對(duì)象:

const UploadFactory = (function () {const createdFlyWeightObjs = {};return {create: function (uploadType) {if (createdFlyWeightObjs[uploadType]) {return createdFlyWeightObjs[uploadType];}return createdFlyWeightObjs[uploadType] = new Upload(uploadType);}}
})();

管理器封裝外部狀態(tài)

現(xiàn)在我們來(lái)完善前面提到的 uploadManager 對(duì)象,它負(fù)責(zé)向 UploadFactory 提交創(chuàng)建對(duì)象的請(qǐng)求,并用一個(gè) uploadDatabase 對(duì)象保存所有 upload 對(duì)象的外部狀態(tài),以便在程序運(yùn)行過(guò)程中給 upload 共享對(duì)象設(shè)置外部狀態(tài),代碼如下:

const uploadManager = (function () {const uploadDatabase = {};return {add: function (id, uploadType, fileName, fileSize) {const flyWeightObj = UploadFactory.create(uploadType);const 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) {const uploadData = uploadDatabase[id];for (const i in uploadData) {flyWeightObj[i] = uploadData[i];}}}
})();

然后是開(kāi)始觸發(fā)上傳動(dòng)作的 startUpload 函數(shù):

let id = 0;
window.startUpload = function (uploadType, files) {for (let i = 0; i < files.length; i++) {const uploadObj = uploadManager.add(++id, uploadType, files[i].fileName, files[i].fileSize);}
};

最后是測(cè)試時(shí)間,運(yùn)行下面的代碼后,可以發(fā)現(xiàn)運(yùn)行結(jié)果跟用享元模式重構(gòu)之前一致:

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

享元模式重構(gòu)之前的代碼里一共創(chuàng)建了 6個(gè) upload 對(duì)象,而通過(guò)享元模式重構(gòu)之后,對(duì)象的數(shù)量減少為 2,更幸運(yùn)的是, 就算現(xiàn)在同時(shí)上傳 2000個(gè)文件,需要?jiǎng)?chuàng)建的 upload 對(duì)象數(shù)量依然是 2。

享元模式的適用性

享元模式是一種很好的性能優(yōu)化方案,但它也會(huì)帶來(lái)一些復(fù)雜性的問(wèn)題,從前面兩組代碼的比較可以看到,使用了享元模式之后,我們需要分別多維護(hù)一個(gè) factory 對(duì)象和一個(gè) manager 對(duì) 象,在大部分不必要使用享元模式的環(huán)境下,這些開(kāi)銷是可以避免的。

享元模式帶來(lái)的好處很大程度上取決于如何使用以及何時(shí)使用,一般來(lái)說(shuō),以下情況發(fā)生時(shí)便可以使用享元模式。

  • 一個(gè)程序中使用了大量的相似對(duì)象。
  • 由于使用了大量對(duì)象,造成很大的內(nèi)存開(kāi)銷。
  • 對(duì)象的大多數(shù)狀態(tài)都可以變?yōu)橥獠繝顟B(tài)。
  • 剝離出對(duì)象的外部狀態(tài)之后,可以用相對(duì)較少的共享對(duì)象取代大量對(duì)象。

可以看到,文件上傳的例子完全符合這四點(diǎn)。

再談內(nèi)部狀態(tài)和外部狀態(tài)

如果順利的話,通過(guò)前面的例子我們已經(jīng)了解了內(nèi)部狀態(tài)和外部狀態(tài)的概念以及享元模式的工作原理。我們知道,實(shí)現(xiàn)享元模式的關(guān)鍵是把內(nèi)部狀態(tài)和外部狀態(tài)分離開(kāi)來(lái)。有多少種內(nèi)部狀態(tài)的組合,系統(tǒng)中便最多存在多少個(gè)共享對(duì)象,而外部狀態(tài)儲(chǔ)存在共享對(duì)象的外部,在必要時(shí)被傳入共享對(duì)象來(lái)組裝成一個(gè)完整的對(duì)象?,F(xiàn)在來(lái)考慮兩種極端的情況,即對(duì)象沒(méi)有外部狀態(tài)和沒(méi)有內(nèi)部狀態(tài)的時(shí)候。

沒(méi)有內(nèi)部狀態(tài)的享元

在文件上傳的例子中,我們分別進(jìn)行過(guò)插件調(diào)用和 Flash 調(diào)用,即 startUpload('plugin', [])startUpload('flash', []),導(dǎo)致程序中創(chuàng)建了內(nèi)部狀態(tài)不同的兩個(gè)共享對(duì)象。也許你會(huì)奇怪,在文件上傳程序里,一般都會(huì)提前通過(guò)特性檢測(cè)來(lái)選擇一種上傳方式,如果瀏覽器支持插件就用插件上傳,如果不支持插件,就用 Flash 上傳。那么,什么情況下既需要插件上傳又需要 Flash 上傳呢?

實(shí)際上這個(gè)需求是存在的,很多網(wǎng)盤都提供了極速上傳(控件)與普通上傳(Flash)兩種模式,如果極速上傳不好使(可能是沒(méi)有安裝控件或者控件損壞),用戶還可以隨時(shí)切換到普通上傳模式,所以這里確實(shí)是需要同時(shí)存在兩個(gè)不同的 upload 共享對(duì)象。

但不是每個(gè)網(wǎng)站都必須做得如此復(fù)雜,很多小一些的網(wǎng)站就只支持單一的上傳方式。假設(shè)我們是這個(gè)網(wǎng)站的開(kāi)發(fā)者,不需要考慮極速上傳與普通上傳之間的切換,這意味著在之前的代碼中作為內(nèi)部狀態(tài)的 uploadType 屬性是可以刪除掉的。 在繼續(xù)使用享元模式的前提下,構(gòu)造函數(shù) Upload 就變成了無(wú)參數(shù)的形式:

const Upload = function(){}; 

其他屬性如 fileName、fileSize、dom 依然可以作為外部狀態(tài)保存在共享對(duì)象外部。在 uploadType 作為內(nèi)部狀態(tài)的時(shí)候,它可能為控件,也可能為 Flash,所以當(dāng)時(shí)最多可以組合出兩個(gè)共享對(duì)象。而現(xiàn)在已經(jīng)沒(méi)有了內(nèi)部狀態(tài),這意味著只需要唯一的一個(gè)共享對(duì)象?,F(xiàn)在我們要改寫創(chuàng)建享元對(duì)象的工廠,代碼如下:

const UploadFactory = (function () {let uploadObj;return {create: function () {if (uploadObj) {return uploadObj;}return uploadObj = new Upload();}}
})();

管理器部分的代碼不需要改動(dòng),還是負(fù)責(zé)剝離和組裝外部狀態(tài)??梢钥吹?#xff0c;當(dāng)對(duì)象沒(méi)有內(nèi)部狀態(tài)的時(shí)候,生產(chǎn)共享對(duì)象的工廠實(shí)際上變成了一個(gè)單例工廠。雖然這時(shí)候的共享對(duì)象沒(méi)有內(nèi)部狀態(tài)的區(qū)分,但還是有剝離外部狀態(tài)的過(guò)程,我們依然傾向于稱之為享元模式。

沒(méi)有外部狀態(tài)的享元

網(wǎng)上許多資料中,經(jīng)常把 Java 或者 C#的字符串看成享元,這種說(shuō)法是否正確呢?我們看看下面這段 Java 代碼,來(lái)分析一下:

// Java 代碼
public class Test {public static void main(String args[]) {String a1 = new String("a").intern();String a2 = new String("a").intern();System.out.println(a1 == a2); // true }
}

在這段 Java 代碼里,分別 new 了兩個(gè)字符串對(duì)象 a1a2。intern 是一種對(duì)象池技術(shù), new String("a").intern()的含義如下。

  • 如果值為 a 的字符串對(duì)象已經(jīng)存在于對(duì)象池中,則返回這個(gè)對(duì)象的引用。
  • 反之,將字符串 a 的對(duì)象添加進(jìn)對(duì)象池,并返回這個(gè)對(duì)象的引用。

所以 a1 == a2 的結(jié)果是 true,但這并不是使用了享元模式的結(jié)果,享元模式的關(guān)鍵是區(qū)別內(nèi)部狀態(tài)和外部狀態(tài)。享元模式的過(guò)程是剝離外部狀態(tài),并把外部狀態(tài)保存在其他地方,在合適的時(shí)刻再把外部狀態(tài)組裝進(jìn)共享對(duì)象。這里并沒(méi)有剝離外部狀態(tài)的過(guò)程,a1a2 指向的完全就是同一個(gè)對(duì)象,所以如果沒(méi)有外部狀態(tài)的分離,即使這里使用了共享的技術(shù),但并不是一個(gè)純粹的享元模式。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 大大減少對(duì)象的創(chuàng)建,降低系統(tǒng)的內(nèi)存,使效率提高。

缺點(diǎn):

  • 提高了系統(tǒng)的復(fù)雜度,需要分離出外部狀態(tài)和內(nèi)部狀態(tài),而且外部狀態(tài)具有固有化的性質(zhì),不應(yīng)該隨著內(nèi)部狀態(tài)的變化而變化,否則會(huì)造成系統(tǒng)的混亂。

總結(jié)

享元模式是為解決性能問(wèn)題而生的模式,這跟大部分模式的誕生原因都不一樣。在一個(gè)存在 大量相似對(duì)象的系統(tǒng)中,享元模式可以很好地解決大量對(duì)象帶來(lái)的性能問(wèn)題。

享元模式的思想與單例比較類似,但是單例模式強(qiáng)調(diào)的是全局唯一,而享元模式則強(qiáng)調(diào)的是內(nèi)存共享。

http://www.risenshineclean.com/news/6169.html

相關(guān)文章:

  • 微信做公司網(wǎng)站怎么做廣州seo網(wǎng)站推廣平臺(tái)
  • 團(tuán)隊(duì)如何分工做網(wǎng)站本周新聞熱點(diǎn)10條
  • 東莞市建設(shè)工程網(wǎng)站網(wǎng)址收錄入口
  • 互聯(lián)網(wǎng)優(yōu)化營(yíng)銷深圳網(wǎng)站優(yōu)化推廣
  • 軟文推廣收費(fèi)南京關(guān)鍵詞seo公司
  • wordpress 前臺(tái)發(fā)布西安seo教程
  • 白城網(wǎng)站建設(shè)seo技術(shù)培訓(xùn)江門
  • 網(wǎng)站里彈窗怎么做黃頁(yè)推廣2021
  • 營(yíng)銷型網(wǎng)站建設(shè)多少錢中國(guó)十大網(wǎng)站排名
  • 邢臺(tái)易優(yōu)網(wǎng)絡(luò)科技有限公司seo網(wǎng)站排名的軟件
  • 江蘇百城建設(shè)有限公司官方網(wǎng)站seo站長(zhǎng)工具查詢系統(tǒng)
  • 怎么建設(shè)自己的卡盟網(wǎng)站2345瀏覽器網(wǎng)頁(yè)版
  • 上海seo服務(wù)朝陽(yáng)seo
  • 北京 做網(wǎng)站百度一下首頁(yè)官網(wǎng)百度
  • 杭州網(wǎng)站建設(shè)公司seo課程多少錢
  • wordpress發(fā)布文章禁用谷歌字體seo關(guān)鍵詞優(yōu)化軟件怎么樣
  • 一家裝修的網(wǎng)站怎么做一鍵優(yōu)化表格
  • 做網(wǎng)站用lunx鏈接交換公司
  • 東莞企業(yè)建站平臺(tái)百度官方入口
  • 做的網(wǎng)站怎么放到域名北京搜索引擎優(yōu)化
  • 教育在線網(wǎng)站怎樣做直播百度推廣網(wǎng)站平臺(tái)
  • 建網(wǎng)站衡水哪家強(qiáng)?做網(wǎng)站哪家好
  • 贛州市城鄉(xiāng)建設(shè)局官方網(wǎng)站風(fēng)云榜百度
  • 代做網(wǎng)站的公司寫軟文用什么軟件
  • 做網(wǎng)站寫的代號(hào)好跟不好的區(qū)別app推廣賺錢
  • b s模式的網(wǎng)站開(kāi)發(fā)營(yíng)銷和銷售的區(qū)別在哪里
  • 碧桂園房地產(chǎn)最新消息北京網(wǎng)站優(yōu)化多少錢
  • visual studio網(wǎng)站開(kāi)發(fā)教程需要優(yōu)化的網(wǎng)站有哪些?
  • 政府網(wǎng)站群 源碼百度搜索推廣技巧
  • 蘇州企業(yè)做網(wǎng)站網(wǎng)絡(luò)輿情監(jiān)測(cè)系統(tǒng)軟件