设计模式-享元模式

假设有个内衣工厂,目前的产品有 50种男式内衣和50种女士内衣,为了推销产品,工厂决定生产一些塑料模特来穿上他们的内衣拍成广告照片。正常情况下需要50个男模特和 50 个女模特,然后让他们每人分别穿上一件内衣来拍照,这就需要100个模特。如果使用共享模式,只需要男女两个模特,然后让他们可以分别穿上不同的内衣来拍照

var Model = function(sex) {
  this.sex = sex; // 性别是内部状态
};

Model.prototype.takePhoto = function() {
  console.log('sex= ' + this.sex + ' underwear=' + this.underwear);
};

var maleModel = new Model('male'),
  femaleModel = new Model('female');

for (var i = 1; i <= 50; i++) {
  maleModel.underwear = 'underwear' + i; // 衣服是外部状态
  maleModel.takePhoto();
};

for (var j = 1; j <= 50; j++) {
  femaleModel.underwear = 'underwear' + j;
  femaleModel.takePhoto();
};

享元模式的关键是如何区别内部状态和外部状态,可以被对象共享的属性通常被划分为内部状态,模特的性别就可以作为内部状态储存在共享对象的内部。外部状态取决于具体的场景,并根据场景而变化,就像例子中每件衣服都是不同的,它们不能被一些对象共享,因此只能被划分为外部状态。

回收池

对象池维护一个装载空闲对象的池子,如果需要对象的时候,不是直接 new,而是转从对象池里获取。如果对象池里没有空闲对象,则创建一个新的对象,当获取出的对象完成它的职责之后, 再进入池子等待被下次获取。

在 Web前端开发中,对象池使用最多的场景大概就是跟 DOM 有关的操作。很多空间和时间都消耗在了 DOM节点上,如何避免频繁地创建和删除 DOM节点就成了一个有意义的话题。对象池技术的应用非常广泛,HTTP连接池和数据库连接池都是其代表应用。

假设我们在开发一个地图应用,地图上经常会出现一些标志地名的小气泡,我们叫它toolTip。

当搜索附近超市时,地图上出现了6个气泡,按照对象池的思想,在第二次搜索开始之前,并不会把第一次创建的2个小气泡删除掉,而是把它们放进对象池。这样在第二次的搜索结果页面里,我们只需要再创建 4个小气泡而不是 6个

var toolTipFactory = (function() {
  var toolTipPool = []; // toolTip 对象池
  return {
    create: function() {
      if (toolTipPool.length === 0) {
        var div = document.createElement('div'); // 创建一个 dom
        document.body.appendChild(div);
        return div;
      } else {
        return toolTipPool.shift(); // 则从对象池中取出一个 dom
      }
    },
    recover: function(tooltipDom) {
      return toolTipPool.push(tooltipDom); // 对象池回收 dom
    }
  }
})();

var ary = [];

// 创建两个气泡
for (var i = 0, str; str = ['A', 'B'][i++];) {
  var toolTip = toolTipFactory.create();
  toolTip.innerHTML = str;
  ary.push(toolTip);
};

// 把气泡添加到回收池
for (var i = 0, toolTip; toolTip = ary[i++];) {
  toolTipFactory.recover(toolTip);
};

// 前两次循环从回收池取气泡,后四次创建新气泡
for (var i = 0, str; str = ['A', 'B', 'C', 'D', 'E', 'F'][i++];) {
  var toolTip = toolTipFactory.create();
  toolTip.innerHTML = str;
  ary.push(toolTip);
};
posted @ 2021-10-07 15:06  wmui  阅读(4)  评论(0编辑  收藏  举报