定义
享元模式是一种用于性能优化的模式,享元模式的核心是运用共享技术有效支持大量细粒度的对象。
如果系统中创建了大量类似的对象导致内存过高,享元模式就非常有用了。
初始享元模式
利用有一个内衣工厂(。。。为啥是这个例子),目前的产品有50种男士的和50种女士的,为了推销产品,需要模特来拍广告,正常情况需要50个男模特和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);
maleMode.takePhoto();
}
for (var j = 0; j < 50; i++) {
var femaleModel = new Model('male', 'underwear' + j);
femaleMode.takePhoto();
}
这看起来好像没什么问题,但是如果内衣变成了10000件呢,甚至更多,那不是要new 10000的对象。其实我们优化一下,我们只需要一个男模特和一个女模特就可以了啊。
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');
for ( var i = 1; i <= 50; i++ ){
maleModel.underwear = 'underwear' + i;
maleModel.takePhoto();
};
for ( var j = 1; j <= 50; j++ ){
femaleModel.underwear = 'underwear' + j;
femaleModel.takePhoto();
};
是不是很开心啦,哈哈
内部状态和外部状态
其实这个例子就是享元模型的原型,享元模型要求对象的属性分为内部状态和外部状态,目标是尽量减少共享对象的数量,如何区分内部状态和外部状态:
- 内部状态存储于对象内部
- 内部状态可以被一些对象共享
- 内部状态独立于具体的场景,通常不会改变
- 外部状态取决于具体的场景,并根据场景而变化,外部状态不能被共享
上面的例子中性别是内部状态,内衣是外部状态。使用享元模式的关键点在于区分内部状态和外部状态
享元模式的通用结构
上面内衣的例子还有两个问题
- 我们通过new显式的创建了两个对象,但是其他系统中可能不是一开始就需要new的
- 我们给model手动的设置了underwear外部状态,但是在复杂的系统中,可能不是很好的办法,因为外部的状态可能很复杂,他们与共享对象之间的联系会很困难
针对第一种,我们可以使用对象工厂来解决,只有当对象是真正需要的时候,它才从工厂中创建出来。
针对第二种,我们可以使用一个管理器来记录对象相关的外部状态,使得这些外部状态通过钩子和共享对象结合起来。
也就是说我们需要一个factory和一个Manager,实现的方式可以参考书籍《JavaScript设计模式与实践》
网友评论