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

    享元模式的适用性

    • 一个程序中使用了大量的相似对象。
    • 由于使用了大量对象,造成很大的内存开销
    • 对象的大多数状态都可以变为外部状态
    • 剥离出对象的外部状态之后,可以用相对较少的共享对象取代大量对象。
      1. // 先定义享元对象
      2. class FlyweightBook {
      3. constructor(category) {
      4. this.category = category
      5. }
      6. // 用于享元对象获取外部状态
      7. getExternalState(state) {
      8. for(const p in state) {
      9. this[p] = state[p]
      10. }
      11. }
      12. print() {
      13. console.log(this.name, this.category)
      14. }
      15. }
      16. // 然后定义一个工厂,来为我们生产享元对象
      17. // 注意,这段代码实际上用了单例模式,每个享元对象都为单例, 因为我们没必要创建多个相同的享元对象
      18. const flyweightBookFactory = (function() {
      19. const flyweightBookStore = {}
      20. return function (category) {
      21. if (flyweightBookStore[category]) {
      22. return flyweightBookStore[category]
      23. }
      24. const flyweightBook = new FlyweightBook(category)
      25. flyweightBookStore[category] = flyweightBook
      26. return flyweightBook
      27. }
      28. })()
      29. // 然后我们要使用享元对象, 在享元对象被调用的时候,能够得到它的外部状态
      30. books.forEach((bookData) => {
      31. // 先生产出享元对象
      32. const flyweightBook = flyweightBookFactory(bookData.category)
      33. const div = document.createElement("div")
      34. div.innerText = bookData.name
      35. div.addEventListener("click", () => {
      36. // 给享元对象设置外部状态
      37. flyweightBook.getExternalState({name: bookData.name}) // 外部状态为书名
      38. flyweightBook.print()
      39. })
      40. document.body.appendChild(div)
      41. })
      在面向对象编程中,有时会重复创建大量相似的对象,当这些对象不能被垃圾回收的时候(比如被闭包在一个回调函数中)就会造成内存的高消耗,在循环体里创建对象时尤其会出现这种情况。享元模式提出了一种对象复用的技术,即我们不需要创建那么多对象,只需要创建若干个能够被复用的对象(享元对象),然后在实际使用中给享元对象注入差异,从而使对象有不同的表现。