Javascript设计模式 - 15 - 享元模式
说明
享元模式是一种用于性能优化的模式,它的核心是运用共享技术来有效支持大量细粒度的对象
下边例子借用了 《javascript 设计模式与开发实践》
内部状态和外部状态
享元模式要求将对象的属性划分为内部状态与外部状态(状态指的是属性),享元模式的目标是减少共享对象的数量
状态划分
- 内部状态存储于对象内部
- 内部状态被一些对象共享
- 内部状态独立于具体的场景,通常不会改变
- 外部状态取决于具体的场景,并根据场景而变化,外部状态不能被共享
状态划分目的
我们可以把所有内部状态指定到一个共享对象上,而外部状态剥离出去,存储在外部,也就是说剥离了外部状态的对象成为共享对象,外部状态在必要的时候被传入共享对象组装成一个完整的对象,虽然组装外部状态的过程需要花费一定的时间,但却可以减少系统中对象的数量, 因此享元模式是一种用时间换空间的优化模式
使用场景
- 一个程序中使用了大量的相似对象
- 由于使用了大量的对象,造成了很大的内存开销
- 对象的大多数状态都可以变为外部状态
- 剥离出对象的外部状态之后,可以使用相对较少的共享对象取代大量对象
// 创建模特类
var Model = function (sex) {
// 内部状态
this.sex = sex;
}
// 快照
Model.prototype.takePhoto = function () {
console.log('sex = ' + this.sex + ' underwear = ' + this.underwear);
}
// 创建男模特和女模特,一共只创建两个
var maleModel = new Model('male');
var femaleModel = new Model('female');
// 穿衣服拍照,装配 underwear 外部状态
for (var i = 0; i < 50; i++) {
maleModel.underwear = 'underwear' + i;
maleModel.takePhoto();
}
for (var i = 0; i < 50; i++) {
femaleModel.underwear = 'underwear' + i;
femaleModel.takePhoto();
}
对象池
对象池维护一个装载空闲对象的池子,如果需要对象时,不直接创建,而是转从对象池里获取,如果对象池里没有空闲对象,则创建一个新对象,当获取的对象完成了他的职责后,再进入池子等待被下次获取,这也是一种共享技术
// 定义气泡创建工厂
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);
},
getToolTipPool: function () {
return toolTipPool;
}
}
}())
// 首次创建
var ary = [];
var strs = [ 'A', 'B' ];
for ( var i = 0; i < strs.length; i++){
var toolTip = toolTipFactory.create();
toolTip.innerHTML = strs[i];
ary.push( toolTip );
}
// 会受到对象池
for (var i = 0; i < ary.length; i++) {
toolTipFactory.recover(ary[i]);
}
console.log(toolTipFactory.getToolTipPool()); // [div, div]
// 再次创建
var strs2 = [ 'A', 'B', 'C', 'D', 'E', 'F' ];
for ( var i = 0; i < strs2.length; i++){
var toolTip = toolTipFactory.create();
toolTip.innerHTML = strs2[i];
ary.push( toolTip );
}
console.log(toolTipFactory.getToolTipPool()); // []
文章列表
- javascript设计模式 – 设计原则
- JavaScript设计模式–高阶函数
- Javascript 设计模式 - 01 - 原型模式
- Javascript 设计模式 - 02 - 单例模式
- Javascript 设计模式 - 03 - 建造者模式
- Javascript 设计模式 - 04 - 工厂模式
- Javascript 设计模式 - 05 - 外观模式
- Javascript 设计模式 - 06 - 代理模式
- Javascript 设计模式 - 07 - 观察者模式(发布订阅模式)
- Javascript 设计模式 - 08 - 策略模式
- Javascript 设计模式 - 09 - 命令模式
- Javascript 设计模式 - 10 - 迭代器模式
- Javascript 设计模式 - 11 - 职责链模式
- Javascript 设计模式 - 12 - 适配器模式
- Javascript 设计模式 - 13 - 模板方法
- Javascript 设计模式 - 14 - 组合模式
- Javascript 设计模式 - 15 - 享元模式
- Javascript 设计模式 - 16 - 中介者模式
- Javascript 设计模式 - 17 - 装饰者模式
- Javascript 设计模式 - 18 - 状态模式