zoukankan      html  css  js  c++  java
  • 设计模式-享元模式

    假设有个内衣工厂,目前的产品有 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);
    };
    
    常用网站: SegmentFault | GitHub | 掘金社区
  • 相关阅读:
    LeetCode题解(14)--Longest Common Prefix
    LeetCode题解(12)--Integer to Roman
    LeetCode题解(13)--Roman to Integer
    LeetCode题解(9)--Palindrome Number
    LeetCode题解(8)--String to Integer (atoi)
    LeetCode题解(7)--Reverse Integer
    LeetCode题解(6)--ZigZag Conversion
    从并发和索引说说innodb和myisam的区别
    thrift基本概念和实例
    fastcgi+lighttpd+c语言 实现搜索输入提示
  • 原文地址:https://www.cnblogs.com/yesyes/p/15375971.html
Copyright © 2011-2022 走看看