javascript 設(shè)計(jì)模式之享元模式原理與應(yīng)用詳解
本文實(shí)例講述了javascript 設(shè)計(jì)模式之享元模式。分享給大家供大家參考,具體如下:
享元模式說(shuō)明
定義:用于解決一個(gè)系統(tǒng)大量細(xì)粒度對(duì)象的共享問(wèn)題:
關(guān)健詞:分離跟共享;
說(shuō)明: 享元模式分單純(共享)享元模式,以及組合(不共享)享元模式,有共享跟不共享之分;單純享元模式,只包含共享的狀態(tài),可共享狀態(tài)是不可變,不可修改的,這是享元的內(nèi)部狀態(tài);當(dāng)然有外部狀態(tài)就有外部狀態(tài),外部狀態(tài)是可變的,不被共享,這個(gè)外部狀態(tài)由客戶端來(lái)管理,是可變化的;外部狀態(tài)與內(nèi)部狀態(tài)是獨(dú)立分開的,外部狀態(tài)一般作為參數(shù)傳入享元對(duì)象內(nèi),但不會(huì)影響內(nèi)部狀態(tài)的值;外部狀態(tài),一用用于獲取共享的享元對(duì)象,或多或少與內(nèi)部狀態(tài)有點(diǎn)關(guān)聯(lián);比如從用戶數(shù)據(jù)表中獲取數(shù)據(jù),傳入一個(gè)外部變量用戶名,再根據(jù)這個(gè)用戶名,獲取該用戶所有對(duì)象狀態(tài)信息;
組合享元模式,配置組合模式來(lái)使用,共享部分只做個(gè)葉子節(jié)點(diǎn),而組合部分是不必共享的,因?yàn)楣步M部分的子葉節(jié)點(diǎn)元素已經(jīng)被緩存,組合部分相當(dāng)一個(gè)分組分類的作用;
享元模式一般會(huì)與工廠模式相結(jié)合使用,用于管理緩存的創(chuàng)建跟維護(hù),享元共享元素的創(chuàng)建一般在工廠類里創(chuàng)建;
享元模式主要用于對(duì)象的共享,使具有相似對(duì)象,或?qū)ο箝g具有太多相似細(xì)粒度的狀態(tài),能共享已經(jīng)創(chuàng)建的對(duì)象,減少對(duì)象的創(chuàng)建,減少對(duì)內(nèi)存的占用,提升優(yōu)化性能;
一種場(chǎng)景:

享元模式結(jié)構(gòu)圖:

像第一張的情況,就可以使用享元模式,因?yàn)楹髢膳诺臓顟B(tài)組合,可能在實(shí)體對(duì)應(yīng)中,多次存在,這時(shí)就可以使用享元的共享特性,來(lái)減少對(duì)象的創(chuàng)建,如有相同的狀態(tài)或組合,就可以獲取緩存的狀態(tài),減少對(duì)象重復(fù)創(chuàng)建,減少內(nèi)存占用;
實(shí)例場(chǎng)景:
1>. 系統(tǒng)各種角色權(quán)限分配;
2>. 系統(tǒng)出現(xiàn)很多種狀態(tài),或組合狀態(tài)需要對(duì)應(yīng)的,而且這種對(duì)應(yīng),可以發(fā)生很多種其他類型對(duì)象上面的,就可以使用享元模式;
實(shí)例源碼: 單純(共享)享元
1. 自定義的 JavaScript Hashtable:
function Hashtable() {
this.values = [];
}
Hashtable.prototype.getJson = function() {
return this.values;
}
Hashtable.prototype.add = function(key, value) {
if (!this.contain(key)) {
this.values.push({key:key, value:value});
}
}
Hashtable.prototype.contain = function(key) {
for (idx in this.values) {
var json = this.values[idx];
if (json.key == key) {
return true;
}
}
return false;
}
Hashtable.prototype.get = function(key) {
var result;
for (idx in this.values) {
var json = this.values[idx];
if (json.key == key) {
result = json;
break;
}
}
return result;
}
Hashtable.prototype.delete = function(key) {
for (idx in this.values) {
var json = this.values[idx];
if (json.key == key) {
delete this.values[idx];
break;
}
}
}
Hashtable.prototype.set = function(key, value) {
if (this.contain(key)) {
this.delete(key);
this.values.push({key:key,value:value});
}
}
2. 享元方法:
function Flyweight(one) {
this.stateOne = one;
}
Flyweight.prototype.operate = function(){
var date = new Date();
console.log(this.stateOne + '-' + Math.random());
};
這里可以處理傳進(jìn)來(lái)的參數(shù)的一些邏輯,也可以初始化從數(shù)據(jù)庫(kù)里提取數(shù)據(jù)緩存保存;
3. 享元工廠:
function FlyweightFactory(){
var hash = new Hashtable();
}
FlyweightFactory.prototype.getFlyweight = function(state) {
var flyweight;
if (hash.contain(state)) {
flyweight = hash.get(state);
} else {
flyweight = new Flyweight(state);
hash.add(state, flyweight);
}
return flyweight;
}
4. Client 使用:
//Client
var factory = new FlyweightFactory();
var fly1, fly2, fly3;
fly1 = factory.getFlyweight('AABB');
fly2 = factory.getFlyweight('CCDD');
fly3 = factory.getFlyweight('CCDD');
fly1.operate();
fly2.operate();
fly3.operate();
輸出:
AABB-0.8621504916809499
CCDD-0.7498800195753574
CCDD-0.7498800195753574
復(fù)合享元模式
1. 復(fù)合享元
function UnShareFlyweight() {
this.state = '';
this.hash = new Hashtable();
}
UnShareFlyweight.prototype.add = function(key, flyweight) {
this.hash.add(key, flyweight);
}
UnShareFlyweight.prototype.operate = function(state) {
var flag = false;
/*
for (idx in this.hash) {
var fly = this.list[idx];
if (fly.stateOne == state) {
flag = true;
break;
}
}
*/
flag = this.hash.contain(state);
flag ? console.log('Exists') : console.log('Not Exists');
}
2. 在修改添加在享元工廠的組合方法:
function FlyweightFactory(){
var hash = new Hashtable();
}
FlyweightFactory.prototype.getFlyweight = function(state) {
var flyweight;
if (hash.contain(state)) {
flyweight = hash.get(state);
} else {
flyweight = new Flyweight(state);
hash.add(state, flyweight);
}
return flyweight;
}
FlyweightFactory.prototype.getComposite = function(list) {
var unFly = new UnShareFlyweight();
var flyweight, state;
for (idx in list) {
state = list[idx];
flyweight = this.getFlyweight(state);
unFly.add(state, flyweight);
}
}
FlyweightFactory.prototype.print = function() {
var jsons = this.hash.getJson();
for (json in jsons) {
json.value.operate();
}
}
3. Client 使用:
var states = ['AABB', 'CDCD', 'AABB', 'CCDD']; var factory = new FlyweightFactory(); factory.getComposite(states); factory.print();
輸出:
AABB-0.8749617566354573
CDCD-0.6991151459515095
CCDD-0.9891050879377872
享元模式其他說(shuō)明
總體來(lái)說(shuō),享元模式用于減少對(duì)象的重復(fù)創(chuàng)建,用于減少內(nèi)存使用,提升性能的結(jié)構(gòu)型模式:
它涉及三個(gè)模式:享元模式,工廠模式,組合模式;
對(duì)于處理多對(duì)多對(duì)應(yīng)而產(chǎn)生的一些數(shù)據(jù)緩存存儲(chǔ),是一個(gè)不錯(cuò)的選擇!
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- javascript設(shè)計(jì)模式之享元模式
- javascript設(shè)計(jì)模式 – 享元模式原理與用法實(shí)例分析
- JavaScript享元模式原理與用法實(shí)例詳解
- JavaScript設(shè)計(jì)模式之享元模式實(shí)例詳解
- JavaScript使用享元模式實(shí)現(xiàn)文件上傳優(yōu)化操作示例
- js設(shè)計(jì)模式之結(jié)構(gòu)型享元模式詳解
- 輕松掌握J(rèn)avaScript享元模式
- 學(xué)習(xí)JavaScript設(shè)計(jì)模式之享元模式
- JS實(shí)現(xiàn)簡(jiǎn)單的圖書館享元模式實(shí)例
- JavaScript設(shè)計(jì)模式之性能優(yōu)化模式享元模式
相關(guān)文章
js登錄滑動(dòng)驗(yàn)證的實(shí)現(xiàn)(不滑動(dòng)無(wú)法登陸)
下面小編就為大家分享一篇js登錄滑動(dòng)驗(yàn)證的實(shí)現(xiàn)(不滑動(dòng)無(wú)法登陸),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
javascript實(shí)現(xiàn)移動(dòng)端觸屏拖拽功能
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)移動(dòng)端觸屏拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
用Javascript評(píng)估用戶輸入密碼的強(qiáng)度(Knockout版)
早上看到博友6點(diǎn)多發(fā)的一篇關(guān)于密碼強(qiáng)度的文章(連接),甚是感動(dòng)(周末大早上還來(lái)發(fā)文)2011-11-11
用JavaScript實(shí)現(xiàn)類似于ListBox功能示例代碼
這篇文章主要介紹了用JavaScript實(shí)現(xiàn)類似于ListBox功能,需要的朋友可以參考下2014-03-03
24個(gè)ES6方法解決JS實(shí)際開發(fā)問(wèn)題(小結(jié))
這篇文章主要介紹了24個(gè)ES6方法解決JS實(shí)際開發(fā)問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
微信小程序?qū)崿F(xiàn)MUI數(shù)字輸入框效果
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)MUI數(shù)字輸入框效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
JS中的提升機(jī)制變量提升函數(shù)提升實(shí)例詳解
這篇文章主要為大家介紹了JS中的提升機(jī)制變量提升函數(shù)提升實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

