享元模式

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-12-15

本文参考:参考1

享元模式(Flyweight):运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销。

通过享元模式可以将共有的数据与方法提取以提高页面效率,主要用于减少创建对象的数量,以减少内存占用和提高性能。享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务,直接返回在内存中已有的对象,避免重新创建。

何时使用:

1、系统中有大量对象
2、这些对象消耗大量内存
3、这些对象的状态大部分可以外部化
4、这些对象可以按照内蕴状态分为很多组,当把外蕴对象从对象剔除出来时,每一组对象都可以用一个对象来代替。
5、系统不依赖于这些对象身份,这些对象是不可分辨的。

<body>
  <div id="container"></div>
  <button id="next">下一页</button>
  <script>
    var Flyweight = function() {
      var created = []; // 缓存共享的对象

      function create() {
        var dom = document.createElement('div');
        document.getElementById('container').appendChild(dom);
        created.push(dom);
        return dom;
      }

      return {
        // 共享对象为5个,小于5个就创建,多余5个就替代
        getDiv() {
          if (created.length < 5) {
            return create(); 
          } else {
            // 获取第一个元素,并插入到最后
            var div = created.shift();
            created.push(div);
            return div;
          }
        }
      }
    }();

    var article = [
      '这是第1条新闻',
      '这是第2条新闻',
      '这是第3条新闻',
      '这是第4条新闻',
      '这是第5条新闻',
      '这是第6条新闻',
      '这是第7条新闻',
      '这是第8条新闻',
      '这是第9条新闻',
      '这是第10条新闻',
    ]
    
    // 初始化5条新闻
    var paper = 0, num = 5, len = article.length;
    for (var i = 0; i < num; i++) {
      if (article[i]) {
        Flyweight.getDiv().innerHTML = article[i];
      }
    }

    // 处理下一页
    document.getElementById('next').onclick = function () {
      if (len < 5) {
        return;
      }
      
      var firstIndex; // // 下一页的第一条数据的下标
      if (len > ++paper * num) { // 有下一页
        firstIndex = paper * num; 
      } else { // 归零
        firstIndex = 0;
        paper = 0;
      }

      for (var j = 0; j < num; j++) {
      if (article[firstIndex+j]) {
          Flyweight.getDiv().innerHTML = article[firstIndex + j];
        } else {
          Flyweight.getDiv().innerHTML = '';
        }
      }
    }
  </script>
</body>

享元模式提醒我们将一个对象的属性划分为内部和外部状态。上例中的 created 数组就是内部状态,可以被对象集合(当前页视图)共享,总是保存着不多余5个的div元素;同时外部状态根据应用场景经常改变,如上例中的每个div的innerHTML就是外部状态。