javascript享元模式和对象池技术

javascript享元模式

享元模式:运用共享技术来有效支持大量细粒度的对象
内部状态:被一些对象共享,独立于具体场景,通常不变
外部状态:取决于具体的场景,并根据场景而变化

文件上传的假设例子

var id = 0;

window.startUpload = function (uploadType, files) {     //uploadType区分是控件还是flash
    for(var i = 0, file; file = files[i++];){
        var uploadObj = new Upload(uploadType, file.fileName, file.fileSize);
        uploadObj.init(id++);                           //给upload对象设置唯一的id
    }
};

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

Upload.prototype.delFile = function (id) {
    uploadManager.setExternalState(id, this);

    if (this.fileSize < 3000){
        return this.dom.parentNode.removeChild(this.dom);
    }

    if (window.confirm('确定要删除文件?'+this.fileName)){
        return this.dom.parentNode.removeChild(this.dom);
    }
};


var UploadFactory = (function () {
    //缓存已经创建的上传类型
    var createdFlyWeightObjs = {};

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

var uploadManager = (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 ];
            }
        }
    }
})();

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

除去功能性的代码,实际上以上逻辑很简单,uploadFactory用来创建上传对象,并对不同的对象做缓存,每次上传修改的仅仅是文件的属性,对不同的文件仅仅是调用上传对象,文件的属性都只是文件自身的属性即外部状态,跟上传对像无关,所以直接存放到uploadmanager中

对象池

对象池技术和享元模式思想不同,但是目的相同,高效利用对象

var toolTipFactory = (function () {
    var toolTipPool = [];       //存放已经创建的对象

    return{
        create: function () {
            if(toolTipPool.length == 0){           //如果对象池为空,需要创建新的对象
                var div = document.createElement('div'); //创建节点
                document.body.appendChild(div);
                return div;
            } else {                            //对象池不为空,直接获取
                return toolTipPool.shift();
            }
        },

        recover: function (tooltipDom) {              //对象的回收
            return toolTipPool.push(tooltipDom);
        }
    }
})();

//第一次使用创建两个
var ary = [];
for (var i = 0, str; str = ['A', 'B'][i++];){
    var toolTip = toolTipFactory.create();
    toolTip.innerHTML = str;
    ary.push(toolTip);
};

//回收对象
for(var i = 0, toolTip; toolTip = ary[i++];){
    toolTipFactory.recover(toolTip);
};

//创建新的对象
for (var i = 0, str; str = ['A', 'B', 'C', 'D', 'E', 'D'][i++];){
    var toolTip = toolTipFactory.create();
    toolTip.innerHTML = str;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值