JavaScript设计模式之享元模式实例详解

作者:霁月时间:2026-10-23 05:23:17浏览:68

本文通过汽车登记的两个对比案例,深入解析JavaScript中的享元模式。第一个案例展示了未使用享元模式时大量相似对象导致的内存消耗问题;第二个案例利用享元模式,将不变状态(内在状态)与可变状态(外部状态)分离,显著降低了空间复杂度。尽管执行时间略有增加,但有效避免了内存溢出风险,适合处理大量相似对象的场景。

享元模式概述

本文详细解析JavaScript中的享元模式,并通过具体实例进行说明,供读者参考学习。

享元模式旨在提升系统性能,特别是优化空间复杂度。它通过共享细粒度对象来避免创建大量结构相似的对象,从而减少内存开销。

未使用享元模式的案例

首先通过一个未使用享元模式的实例,分析其运行时间和空间占用情况。

设定场景:需要对城市中的汽车进行登记管理。

第一步,定义汽车类。


/**
* 制造商
* 型号
* 拥有者
* 车牌号码
* 最近一次登记日期
*/
var Car = function(make,model,year,owner,tag,renewDate){
    this.make = make;
    this.model = model;
    this.year = year;
    this.owner = owner;
    this.tag = tag;
    this.renewDate = renewDate;
    this.getMake = function(){
      return this.make;
    }
}

第二步,引入装饰者模式以计算函数执行耗时。


//装饰者 .. 计算函数的耗时
var simpleProfiler = function(componet){
    this.componet = componet;
    this.action = function(methodName){
      var self = this;
      var method = componet[methodName];
      //如果是函数那就进行装饰
      if(typeof method == "function"){
        var startDate = new Date().getTime();//开始时间
        method.apply(self.componet,arguments);
        var endDate = new Date();//结束时间
        alert(endDate - startDate);
      }
    }
}

第三步,构建具体实例,假设需要登记4150000辆汽车。


var ca = new Array();
function addCar(){
    this.begin = function(){
      for (var i = 0; i < 4150000; i++) {
        ca.push(new Car("BMW","宝马","2017-10-18",
          "","GBMW88","2017-10-19"));
      }
    }
}
new simpleProfiler(new addCar()).action("begin")

使用享元模式的案例

接下来展示使用享元模式的第二个实例。

第一步,重新定义汽车类,仅包含不变状态。


/**
* 制造商
* 型号
* 拥有者
* 车牌号码
* 最近一次登记日期
*/
var Car = function(make,model,year){
    this.make = make;
    this.model = model;
    this.year = year;
    this.getMake = function(){
      return this.make;
    }
}

第二步,使用单例模式的简单工厂来管理对象创建。


//单例模式的简单工厂
  var myCarInfo = function(){
    this.createCar = function(make,model,year,owner,tag,renewDate){
      var c = carInfoFactory(make,model,year);
      c["owner"] = owner;
      c["tag"] = tag;
      c["renewDate"] = renewDate;
      return c;
    }
  }
  var carInfoFactory = (function(){
    var carInfo = {};
    return function(make,model,year){
      if(carInfo[make+model+year]){
        return carInfo[make+model+year];
      }else{
        var newCar = new Car(make,model,year);
        carInfo[make+model+year] = newCar;
        return newCar;
        a
      }
    }
  })();

第三步,同样处理4150000辆汽车的登记需求。


var test = new myCarInfo();
var startDate = new Date().getTime();
var ca = new Array();
for (var i = 0; i < 4150000; i++) {
    ca.push(test.createCar("BMW","宝马","2017-10-18",
          "","GBMW88","2017-10-19"))
}
var endDate = new Date();
alert(endDate - startDate);

两种模式的对比分析

对比两个实例可知:未使用享元模式的方案执行时间较短,但空间消耗巨大;使用享元模式的方案执行时间稍长,但显著降低了空间消耗。

第一种情况的图解显示,每次操作都生成相同的实例,导致内存重复占用。

享元模式概述

第二种情况图解展示了享元模式的核心:将对象状态分为内在部分(不变)和外部状态(变化)。

享元模式概述

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》。

希望本文所述内容对大家的JavaScript程序设计有所帮助。

作者最新文章