享元模式是一种用于性能优化的模式,其主要方式是通过运用共享技术来实现复杂对象总量的减少。将结构整体合理划分内部状态和外部状态,内部状态是那种不变化的,稳定的,也可以称之为
享元
,外部状态是那种变化的,不定的。
先举个例子:餐馆,如果使用一次性筷子,就餐次数增加一次,就需要多一双筷子。
那么,假如每天500
个就餐次数,一年就是500 × 365 = 182500
。
用代码实现一次性筷子的创建和销毁情况:
// 筷子序列号
var serialNumber = 1;
// 筷子构造函数
var Chopsticks = function (serialNumber) {
this.serialNumber = serialNumber;
}
// 筷子管理
var chopsticksManager = (function () {
var outerData = []
return {
add: function (count) {
for (var i = 0; i < count; i++) {
outerData.push(new Chopsticks(serialNumber++))
}
return outerData;
},
destroy: function () {
while (outerData.length) {
outerData.pop();
}
},
}
})()
// 一次性筷子的创建
var chopsticksArr = chopsticksManager.add(182500)
// 一次性筷子的销毁
chopsticksManager.destroy()
在当前例子中,我们定义了筷子构造函数,然后通过chopsticksManager
进行筷子的管理。我们不考虑筷子分批次创建和分批次销毁的情况,我们汇总成一次进行处理。通过chopsticksArr = chopsticksManager.add(182500)
的方式去创建182500
双筷子,使用后,再通过chopsticksManager.destroy()
的方式去销毁筷子,这个过程中我们进行了182500
次筷子的创建。
为了减少一次性筷子,使用公筷,我们定义1000
双公筷。
用代码实现使用公筷后,使用公筷和公筷回收的情况:
// 筷子序列号
var serialNumber = 1;
// 筷子构造函数
var Chopsticks = function (serialNumber, type) {
this.serialNumber = serialNumber;
this.type = type;
}
// 筷子管理
var chopsticksManager = (function () {
var innerData = [] // 提升为内部状态的享元池
var recycleData = [] // 公筷回收池
return {
// 创建公筷
add: function (count) {
for (var i = 0; i < count; i++) {
innerData.push(new Chopsticks(serialNumber++))
}
return innerData;
},
// 使用公筷
use: function (count) {
for (let i = 0; i < count; i++) {
var item = innerData.pop()
item.type = 'hasUsed' // 标注为已经被使用
recycleData.push(item);
}
},
// 回收公筷
recycle: function () {
let recycleDataLength = recycleData.length
for (let i = 0; i < recycleDataLength; i++) {
var item = recycleData.pop()
item.type = 'hasRecycled'; // 标注为已经被回收
innerData.push(item);
}
},
}
})()
// 公筷创建,公筷创建是日常客流的二倍,以防客流突然增多
var chopsticksArr = chopsticksManager.add(1000);
// 有一天客流325
chopsticksManager.use(325); // 筷子的使用
chopsticksManager.recycle(); // 筷子的回收
// 有一天客流732
chopsticksManager.use(732); // 筷子的使用
chopsticksManager.recycle(); // 筷子的回收
// 有一天客流210
chopsticksManager.use(210); // 筷子的使用
chopsticksManager.recycle(); // 筷子的回收
// 日复一日,年复一年,筷子的使用就从公筷池中使用,洗净消毒回收
在当前例子中,我们定义了筷子构造函数,然后通过chopsticksManager
进行筷子的管理。通过chopsticksArr = chopsticksManager.add(1000)
的方式去创建1000
双公筷,通过chopsticksManager.use(325)
的方式去使用,使用后再通过chopsticksManager.recycle()
的方式去洗净消毒回收。
那么,在整个升级改造过程中,我们节省了超十八万双
一次性筷子。
一次性筷子是没有享元的情况,使用公筷后,1000
双公筷相当于1000
个享元,在公筷池中,我们可以进行公筷的取出,和公筷清洗和消毒后的放回。就相当于,我们在享元池中进行享元的取出和放回。