享元模式
享元(flyweight)模式
是一种用于性能优化的模式,享元模式的核心就是运用共享技术来有效支持大量细粒度的对象。
享元模式
要求将对象的属性划分为内部状态与外部状态(状态在这里通常指属性)。
享元模式
的目标是尽量减少共享对象的数量,关于如何划分内部状态和外部状态
例子:假设有个内衣工厂,目前的产品有50种男式内衣和50种女士内衣,为了推销产品,工厂决定生产一些塑料模特来穿上他们的内衣拍成广告照片。正常情况下需要50个男模特和50个女模特,然后让他们每人分别穿上一件内衣来拍照。
const ModelT = function (sex) {
this.sex = sex;
};
ModelT.prototype.takePhoto = function () {
console.log('sex= ' + this.sex + 'underwear = ' + this.underwear);
};
let maleModel = new ModelT('male');
let femaleModel = new ModelT('female');
for (var i = 1; i <= 50; i++) {
maleModel.underwear = 'underwear' + i;
maleModel.takePhoto();
};
for (var i = 1; i <= 50; i++) {
femaleModel.underwear = 'underwear' + i;
femaleModel.takePhoto();
};
怎样划分内部状态和外部状态?
❏ 内部状态存储于对象内部。
❏ 内部状态可以被一些对象共享。
❏ 内部状态独立于具体的场景,通常不会改变。
❏ 外部状态取决于具体的场景,并根据场景而变化,外部状态不能被共享。
对象池例子
对象池
维护一个装载空闲对象的池子,如果需要对象的时候,不是直接new,而是转从对象池里获取。如果对象池里没有空闲对象,则创建一个新的对象,当获取出的对象完成它的职责之后,再进入池子等待被下次获取。
// 先定义一个获取小气泡节点的工厂,作为对象池的数组成为私有属性被包含在工厂闭包里,这个工厂有两个暴露对外的方法,create表示获取一个div节点,recover表示回收一个div节点
var toolTipFactory = (function () {
var toolTipPool = []; // toolTip对象池
// console.log('toolTipPool',toolTipPool);
return {
create: function () {
if (toolTipPool.length === 0) { //如果对象池为空
var div = document.createElement('div'); //创建一个domdocument.body.appendChild( div );
return div;
} else { //如果对象池里不为空
return toolTipPool.shift(); //则从对象池中取出一个dom
}
},
recover: function (tooltipDom) {
return toolTipPool.push(tooltipDom); //对象池回收dom
}
}
})();
var ary = [];
// 目前需要创建2个小气泡节点,为了方便回收,用一个数组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);
};
// 再创建6个小气泡
var aryB = []
for (var i = 0, str; str = ['A', 'B', 'C', 'D', 'E', 'F'][i++];) {
var toolTip = toolTipFactory.create();
toolTip.innerHTML = str;
aryB.push(toolTip);
};
console.log('aryB', aryB);
在什么情况下使用享元模式?
❏ 一个程序中使用了大量的相似对象。
❏ 由于使用了大量对象,造成很大的内存开销。
❏ 对象的大多数状态都可以变为外部状态。
❏ 剥离出对象的外部状态之后,可以用相对较少的共享对象取代大量对象。