1.描述:享元模式是一种用于性能优化的模式,享元模式的目标是尽量减少共享对象的数量,其关键在于划分出内部属性和外部属性。
2.内部属性和外部属性:内部属性可以理解为对象可共享的属性,比如:不同人都有的名字属性;外部属性可以理解为同一对象在不同场景下就不同的属性,比如:衣服,一个人冬天穿的衣服和夏天穿的衣服是不同的。
如何划分内部属性和外部属性:
- 内部属性存储于对象内部
- 内部属性可以被一些对象共享
- 内部属性独立于具体的场景,通常不会改变
- 外部属性取决于具体的场景,并根据场景而变化,外部状态不能被共享
3.享元模式适用场景:
- 一个程序中使用了大量相似的对象
- 由于使用了大量对象,造成很大的内存开销
- 对象大多数属性可以变为外部属性
- 剥离出对象的外部状态之后,可以用相对较少的共享对象取代大量对象
4.实例:100种内衣拍照,男女各50种,生产模特并拍照
不使用享元模式编程实现
var Model = function(sex,underwear){
this.sex = sex;
this.underwear = underwear;
};
Model.prototype.takePhoto = function(){
console.log('sex='+this.sex+' underwear='+this.underwear);
};
for(var i=0;i<50;i++){
var maleModel = new Model('male','underwear'+i);
maleModel.takePhoto();
}
for(var j=0;j<50;j++){
var femaleModel = new Model('female','underwear'+i);
femaleModel.takePhoto();
}
使用享元模式实现
内部属性:sex
外部属性:underwear
var Model = function(sex){
this.sex = sex;
};
Model.prototype.takePhoto = function(){
console.log('sex='+this.sex+' underwear='+this.underwear);
};
var ModelFactor = (function(){
var createdModelObjs = {};
return {
create:function(sex){
if(createdModelObjs[sex]){
return createdModelObjs[sex];
}
return createdModelObjs[sex] = new Model(sex);
}
};
})();
var modelManeger = (function(){
return {
produceModel:function(sex,underwear){
var modelObj = ModelFactor.create(sex);
modelObj.underwear = underwear;
return modelObj ;
}
};
})();
for(var j=0;j<50;j++){
var maleModel = modelManeger('male','underwear'+i);
maleModel.takePhoto();
}
for(var j=0;j<50;j++){
var femaleModel = modelManeger('female','underwear'+i);
femaleModel.takePhoto();
}
这时候我们可以看到,前一种方法每一个模特都需要创建一个对象,而使用享元模式之后是一个性别创建一个模特对象,大大减少了创建对象的数量,减少了内存的占用。当然,实际情况远没这么简单,这里作为一个实例分析,有必要将其简化。
实际上,除了享元模式之外,对象池+事件委托也能达到此类性能优化的目的。