JavaScript享元模式

享元(flyweight)模式是一種用于性能優(yōu)化的模式,“fly”在這里是蒼蠅的意思,意為蠅量級。享元模式的核心是運用共享技術(shù)來有效支持大量細粒度的對象。
享元模式是使用同一個對象處理大量同種業(yè)務(wù)的模式,其能夠避免創(chuàng)建大量相似對象,減少內(nèi)存使用。

享元模式將對象分為內(nèi)部狀態(tài)和外部狀態(tài)。當(dāng)兩者組合成一個完整對象時使用。

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

使用享元模式對列表進行業(yè)務(wù)處理

//元對象
var Upload = function( uploadType ){
    this.uploadType = uploadType;  //內(nèi)部狀態(tài)
};

Upload.prototype.delFile = function( id ){
    uploadManager.setExternalState( id, this );  //將uploadManager管理的外部狀態(tài)綁定于元對象
    
    if( this.fileSize < 3000 ){
        //根據(jù)uploadType進行業(yè)務(wù)處理
        //....
        
        return this.dom.parentNode.removeChild( this.dom );
    }
    
    if( window.confirm('確定要刪除該文件嗎?' + this.fileName )){
        return this.dom.parentNode.removeChild( this.dom );
    }
};

//使用工廠進行實例化,相同內(nèi)部狀態(tài)只實例化一次
var UploadFactory = (function(){
    var createdFlyWeightObjs = {};
    
    return {
        create: function( uploadType ){
            if( createdFlyWeightObjs[ uploadType ] ){
                return createdFlyWeightObjs[ uploadType ];
            }
            
            return createdFlyWeightObjs[ uploadType ] = new Upload( uploadType );
        }
    }
})();

//管理器封裝外部狀態(tài)
var uploadManager = (function(){
    var uploadDatabase = {},  //存儲外部狀態(tài)
    
    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 = uploadManager.add( ++id,uploadType, file.fileName, file.fileSize );
    }
};

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

對象池技術(shù)與享元模式類似,但對象池沒有主動分離內(nèi)部狀態(tài)和外部狀態(tài)。以下為對象池代碼:

var objectPoolFactory = function( createObjFn ){
    var objectPool = [];
    
    return {
        create: function(){
            var obj = objectPool.length === 0?
                createObjFn.apply( this,arguments ) : objectPool.shift();
            return obj;
        },
        recover: function( obj ){
            objectPool.push( obj );
        }
    }
};

//對象池的使用
var iframeFactory = objectPoolFactory( function(){
    var iframe = document.createElement('iframe');
        document.body.appendChild( iframe );
    
    iframe.onload = function(){
        iframe.onload = null;  //防止iframe重復(fù)加載的bug
        iframeFactory.recover( iframe );  //iframe加載完成之后回收節(jié)點
    }
    
    return iframe;
    
});

var iframe1 = iframeFactory.create();
iframe1.src = 'http://baidu.com';

var iframe2 = iframeFactory.create();
iframe2.src = 'http://QQ.com';

setTimeout(function(){
    var iframe3 = iframeFactory.create();
    iframe3.src = 'http://163.com';
},3000 );
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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