JavaScript设计模式之享元模式

享元模式

定义

  享元模式:运用共享技术来有效地支持大量细粒度对象的复用,以减少创建的对象的数量。
  享元模式的主要思想是共享细粒度对象,也就是说如果系统中存在多个相同的对象,那么只需共享一份就可以了,不必每个都去实例化每一个对象,这样来精简内存资源,提升性能和效率。

内部状态与外部状态

  享元模式的目标是尽量减少共享对象的数量,关于如何划分内部状态和外部状态,下面的几条经验提供了一些指引:

  • 内部状态存储于内部对象
  • 内部状态可以被一些对象共享
  • 内部状态独立于具体的场景,通常不会改变
  • 外部状态取决于具体的场景,并根据具体的场景而变化,外部状态不能被共享
      这样一来,我们便可以把所有内部状态相同的对象都指定为同一共享对象。而外部状态可以从对象身上剥离出来,并存储在外部。

示例

  文件上传的例子,上传文件方式有插件、Flash 和 表单上传,当用户选择了文件之后,插件 和 Flash 会通知 Window 下的全局 JavaScript 函数,它的名字是 startUpload, 用户选择的文件列表被组合成一个数组 files 塞进该函数的参数列表里,代码如下:

// 剥离外部状态
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 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 UploadFactory = (function(){
	var createedFlyWeightObjs = {};
	
	return {
		create: function(uploadType) {
			if(createedFlyWeightObjs[uploadType]) {
				return createedFlyWeightObjs[uploadType]
			}
			return  createedFlyWeightObjs[uploadType] = new Upload(uploadType);
		}
	}
})();

测试代码:

var id = 0;

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

startUpload('plugin',[
	{
		fileName: '1.txt',
		fileSize: 1000
	},
	{
		fileName: '2.txt',
		fileSize: 4000
	},
	{
		fileName: '3.txt',
		fileSize:2000
	}
]);

startUpload('flash',[
	{
		fileName: '4.txt',
		fileSize: 1000
	},
	{
		fileName: '5.txt',
		fileSize: 4000
	},
	{
		fileName: '6.txt',
		fileSize:2000
	}
]);

有几种上传方式就最多有几个对象。

总结

  享元模式是为解决性能问题而生的模式,这跟大部分模式的诞生原因都不一样。在一个存在大量相似对象的系统中,享元模式可以很好地解决大量对象带来的性能问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值