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