享元模式
享元模式(Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。享元模式区分了内部状态和外部状态,所以我们可以通过设置不同的外部状态使得相同的对象可以具备一些不同的特性,而内部状态设置为相同部分。在我们的程序设计过程中,我们可能会需要大量的细粒度对象来表示对象,如果这些对象除了几个参数不同外其他部分都相同,这个时候我们就可以利用享元模式来大大减少应用程序当中的对象。如何利用享元模式呢?这里我们只需要将他们少部分的不同的部分当做参数移动到类实例的外部去,然后再方法调用的时候将他们传递过来就可以了。
现在假设一个一个情景, 有男女服装个100套, 需要租模特来试穿衣服, 传统做法就是男女各找100个模特试穿每一见衣服
// 雇佣模特
let HireModel = function(sex,clothes){
this.sex = sex;
this.clothes = clothes;
};
HireModel.prototype.wearClothes = function(){
console.log(this.sex + '试穿' + this.clothes);
};
/*******试穿**********/
for(let i=0;i<100;i++){
let model = new HireModel('male','第'+i+'款男衣服');
model.wearClothes();
}
for(let i=0;i<100;i++){
let model = new HireModel('female','第'+i+'款女衣服');
model.wearClothes();
}
享元模式可以简单的理解为 单例模式 + 工厂模式 + 管理器 , 管理器对外部状态进行管理组合成完整的对象
结构:
采用享元模式则只需要男女模特各一名, 试穿所有衣服
//雇佣模特
var HireModel = function(sex){
//内部状态是性别
this.sex = sex;
};
HireModel.prototype.wearClothes = function(clothes){
console.log(this.sex+"穿了"+clothes);
};
//工厂模式,负责造出男女两个模特
var ModelFactory = (function(){
var cacheObj = {};
return {
create:function(sex){
//根据sex分组
if(cacheObj[sex]){
return cacheObj[sex];
} else {
cacheObj[sex] = new HireModel(sex);
return cacheObj[sex];
}
}
};
})();
//模特管理
var ModelManager = (function(){
//容器存储:1.共享对象 2.外部状态
var vessel = {};
return {
add:function(sex,clothes,id){
//造出共享元素:模特
var model = ModelFactory.create(sex);
//以id为键存储所有状态
vessel[id] = {
model:model,
clothes:clothes
};
},
wear:function(){
for(var key in vessel){
//调用雇佣模特类中的穿衣服方法。
vessel[key]['model'].wearClothes(vessel[key]['clothes']);
}
}
};
})();
/*******通过运行时间测试性能**********/
for(var i=0;i<100;i++){
ModelManager.add('male','第'+i+'款男衣服',i);
ModelManager.add('female','第'+i+'款女衣服',i);
}
ModelManager.wear();
由于享元模式需要区分外部状态和内部状态,使得应用程序在某种程度上来说更加复杂化了。
为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。使用场景:
对象的属性可以拆分
对象的变量是一部分可以变动另外享元模式其实使用的非常广泛。只要对象处于反复创建的环境中,并且每个对象有部分属性是共通的那么我们就能使用享元模式。符合这种场景的比如 java 中 string 的常量池,就是享元模式。还有jDK中的类文件放在方法区也是享元模式的一种。在互联网应用中通常我们描述的叫XX池的东西都是使用的享元模式。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。