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] = flyweightBookreturn flyweightBook}})()// 然后我们要使用享元对象, 在享元对象被调用的时候,能够得到它的外部状态books.forEach((bookData) => {// 先生产出享元对象const flyweightBook = flyweightBookFactory(bookData.category)const div = document.createElement("div")div.innerText = bookData.namediv.addEventListener("click", () => {// 给享元对象设置外部状态flyweightBook.getExternalState({name: bookData.name}) // 外部状态为书名flyweightBook.print()})document.body.appendChild(div)})
 
