https://www.jianshu.com/p/536e1f6d0607
https://www.imyangyong.com/javascript-design-pattern/%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F.html
享元模式的适用性
- 一个程序中使用了大量的相似对象。
- 由于使用了大量对象,造成很大的内存开销
- 对象的大多数状态都可以变为外部状态
- 剥离出对象的外部状态之后,可以用相对较少的共享对象取代大量对象。
在面向对象编程中,有时会重复创建大量相似的对象,当这些对象不能被垃圾回收的时候(比如被闭包在一个回调函数中)就会造成内存的高消耗,在循环体里创建对象时尤其会出现这种情况。享元模式提出了一种对象复用的技术,即我们不需要创建那么多对象,只需要创建若干个能够被复用的对象(享元对象),然后在实际使用中给享元对象注入差异,从而使对象有不同的表现。// 先定义享元对象
class FlyweightBook {
constructor(category) {
this.category = category
}
// 用于享元对象获取外部状态
getExternalState(state) {
for(const p in state) {
this[p] = state[p]
}
}
print() {
console.log(this.name, this.category)
}
}
// 然后定义一个工厂,来为我们生产享元对象
// 注意,这段代码实际上用了单例模式,每个享元对象都为单例, 因为我们没必要创建多个相同的享元对象
const flyweightBookFactory = (function() {
const flyweightBookStore = {}
return function (category) {
if (flyweightBookStore[category]) {
return flyweightBookStore[category]
}
const flyweightBook = new FlyweightBook(category)
flyweightBookStore[category] = flyweightBook
return flyweightBook
}
})()
// 然后我们要使用享元对象, 在享元对象被调用的时候,能够得到它的外部状态
books.forEach((bookData) => {
// 先生产出享元对象
const flyweightBook = flyweightBookFactory(bookData.category)
const div = document.createElement("div")
div.innerText = bookData.name
div.addEventListener("click", () => {
// 给享元对象设置外部状态
flyweightBook.getExternalState({name: bookData.name}) // 外部状态为书名
flyweightBook.print()
})
document.body.appendChild(div)
})