美文网首页
设计模式 -- 享元模式

设计模式 -- 享元模式

作者: noyanse | 来源:发表于2019-07-16 23:20 被阅读0次
  • 公用某些资源
    与数据库连接池,HTTP连接池很相似
    使用HTTP连接池管理长连接,可以复用HTTP连接,省去创建TCP连接的3次握手和关闭TCP连接的4次挥手的步骤,降低请求响应的时间

使用场景:

  1. 如果一个程序中大量使用相同或相似对象,那么可以考虑引入享元模式
  2. 如果使用了相同或相似对象,并造成了较大的内存开销
  3. 对象的大多数状态可以被转变为外部状态
  4. 剥离出对象的外部状态后,可以用相对较少的共享对象取代大量对象
let examCardNum = 0 // 驾考车总数

class ExamCar {
    constructor(carType) {
        examCardNum++
        this.cardId = examCardNum
        this.carType = carType ? '手动挡' : '自动挡'
        this.usingState = false // 是否正在占用
    }

    // 在本车上考试
    examine(candidateId) {
        return new Promise(resolve => {
            this.usingState = true
            console.log(`考生 ${candidateId} 在 ${this.carType}驾考车-${this.cardId}上考试`)
            setTimeout(() => { // 0 - 2s 考完后
                this.usingState = false
                resolve()
            }, Math.random() * 2000)
        })
    }
}

// 手动挡汽车对象池
ManualExamCarPool = {
    _pool: [], // 驾考车对象池
    _candidateQueue: [], // 考生队列

    // 注册考生 ID 列表
    registCandidates(candidateList) {
        candidateList.forEach(candidateId => this.registCandidate(candidateId))
    },

    // 注册手动挡考生
    registCandidate(candidateId) {
        const examCar = this.getManualExamCar() // 找一个未被占用的手动挡驾考车
        if (examCar) {
            examCar.examine(candidateId) // 开始考试, 考完了让队列中的下一个考生开始考试
                .then(() => {
                    const nextCandidateId = this._candidateQueue.length && this._candidateQueue.shift()
                    nextCandidateId && this.registCandidate(nextCandidateId)
                })
        } else { // 如果没有空车,将考生推入队列
            this._candidateQueue.push(candidateId)
        }
    },

    // 注册手动挡车
    initManualExamCar(manualExamCarNum) {
        for(let i = 0; i <= manualExamCarNum; i++) {
            this._pool.push(new ExamCar(true))
        }
    },

    // 获取状态为未被占用的手动挡车
    getManualExamCar() {
        return this._pool.find(car => !car.usingState)
    }
}

ManualExamCarPool.initManualExamCar(3) // 一共三辆考车
ManualExamCarPool.registCandidates([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) // 10个考生来考试

相关文章

网友评论

      本文标题:设计模式 -- 享元模式

      本文链接:https://www.haomeiwen.com/subject/itzxlctx.html