前言
享元模式属于结构型模式,这个类型的设计模式总结出了 类、对象组合后的经典结构,将类、对象的结构和使用解耦了,花式的去借用对象。
享元模式
使用场景:当需要复用大量的对象,这大量的对象几乎都差不多,频繁的去创建导致性能开销暴涨,这时候可以将这些对象存起来,之后需要用的时候,直接从缓存中去拿,用完再初始化一下状态,最后再放入容器中。这样就可以频繁的使用了,比如服务器端的线程池、连接池,它们都是享元模式的具体体现。
理解:类、对象的结构和使用解耦,享元模式以内存来换取时间,减少了重复的对象创建开辟内存的操作。享元模式的使用需要根据应用场景,如果根本不需要使用享元模式而强行去使用它,就会造成多余的性能开销了,就像你开店,本来开的是个小饭馆,你却请了一个大酒店那么多的员工,那可不就太浪费了。
namespace struct_mode_05 {
// 接口
interface IServer {
recruit(worker: Worker): IServer
work(guest: Guest): IServer
}
// 顾客:操作对象
class Guest {
name: string
isAccept: boolean = false
constructor(name: string) {
this.name = name
}
}
// 工人:元素
class Worker {
name: string
isWorker: boolean = false
constructor(name: string) {
this.name = name
}
work(guest: string) {
console.log(`${this.name}正在服务${guest}`)
}
}
// 餐厅:享元工厂
class DiningRoom implements IServer {
workerList: Array<Worker> = []
recruit(worker: Worker): IServer {
this.workerList.push(worker)
return this
}
work(guest: Guest): IServer {
const obj = this.workerList.find(item => !item.isWorker)
if (obj) {
obj.isWorker = true
guest.isAccept = true
obj.work(guest.name)
setTimeout(() => {
obj.isWorker = false
}, 3000 * Math.random())
} else {
console.log('已没有工人可以提供服务,客户' + guest.name + ' 请稍等。。。 ')
setTimeout(() => {
this.work(guest)
}, 3000 * Math.random())
}
return this
}
}
// 使用
// 餐厅招人
const diningRoom = new DiningRoom()
Array(12).fill(true).forEach((item, itemIndex) => {
diningRoom.recruit(new Worker('工人' + itemIndex))
});
// 客人扎堆
const guestList = Array(30).fill(true).map((item, itemIndex) => {
return new Guest('客人' + itemIndex)
}).sort(() => Math.random() - 0.5)
// 一堆客人进入餐厅接受服务
guestList.forEach(guest => {
diningRoom.work(guest)
})
// 轮询判断所有客户是否已经全部接受服务
let acceptId = setInterval(() => {
const acceptGuest = guestList.filter(guest => guest.isAccept)
if (acceptGuest.length === guestList.length) {
console.log('所有顾客接受服务完毕!!!!!')
clearInterval(acceptId)
}
}, 1000)
}