用享元模式来解释:提倡使用公筷,不使用一次性筷子

1,918 阅读3分钟

享元模式是一种用于性能优化的模式,其主要方式是通过运用共享技术来实现复杂对象总量的减少。将结构整体合理划分内部状态和外部状态,内部状态是那种不变化的,稳定的,也可以称之为享元,外部状态是那种变化的,不定的。

先举个例子:餐馆,如果使用一次性筷子,就餐次数增加一次,就需要多一双筷子。

image.png

那么,假如每天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双公筷。

image.png

用代码实现使用公筷后,使用公筷和公筷回收的情况:

// 筷子序列号
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个享元,在公筷池中,我们可以进行公筷的取出,和公筷清洗和消毒后的放回。就相当于,我们在享元池中进行享元的取出和放回。