享元(flyweight)模式是一种用于性能优化的模式,“fly”在这里是苍蝇的意思,意为蝇量
级。享元模式的核心是运用共享技术来有效支持大量细粒度的对象。
假设有个内衣工厂,目前的产品有 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 = 1; i <= 50; i++) { var maleModel = new Model(‘male‘, ‘underwear‘ + i); maleModel.takePhoto(); }; for(var j = 1; j <= 50; j++) { var femaleModel = new Model(‘female‘, ‘underwear‘ + j); femaleModel.takePhoto(); };
要得到一张照片,每次都需要传入 sex 和 underwear 参数,如上所述,现在一共有 50种男内
衣和 50 种女内衣,所以一共会产生 100 个对象。如果将来生产了 10000 种内衣,那这个程序可
能会因为存在如此多的对象已经提前崩溃。
下面我们来考虑一下如何优化这个场景。虽然有 100 种内衣,但很显然并不需要 50 个男
模特和 50 个女模特。其实男模特和女模特各自有一个就足够了,他们可以分别穿上不同的内
衣来拍照。
现在来改写一下代码,既然只需要区别男女模特,那我们先把 underwear 参数从构造函数中
移除,构造函数只接收 sex 参数:
var Model = function(sex) { this.sex = sex; }; Model.prototype.takePhoto = function() { console.log(‘sex= ‘ + this.sex + ‘ underwear=‘ + this.underwear); }; //分别创建一个男模特对象和一个女模特对象: var maleModel = new Model(‘male‘), 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(); };
可以看到,改进之后的代码,只需要两个对象便完成了同样的功能。