享元模式(Flyweight),运行共享技术有效地支持大量细粒度的对象,避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类)。
先观察以下场景:
// Car类:属性: 出厂商,型号,出厂日期,拥有者,车牌号,登记日期
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;
};
Car.prototype = {
constructor : Car,
getMake : function(){
return this.make;
},
getModel : function(){
return this.model;
},
getYear : function(){
return this.year;
},
renewRegistration : function(newRenewDate){
this.renewDate = newRenewDate;
}
};
var arr = [];
var stime = new Date().getTime();
for(var i = 0; i < 5000000;i++){
arr.push(new Car('上海大众', '辉腾', '2017-06-09', 'Jagger', '浙A10086', '2017-07-01'));
}
var etime = new Date().getTime();
alert(etime - stime);
// 运行时间 1.5s; 内存占用 505M;
// 内存占用太多,看来有必要优化一下
// 享元模式:内存优化
/*
享元模式:
内在数据(出厂商,型号,出厂日期 等不会发生变化的数据)
外在数据(拥有者,车牌号,登记日期 等会变化的数据)
*/
// Car类:属性: 出厂商,型号,出厂日期,拥有者,车牌号,登记日期
var Car = function(make, model, year){
// 内在数据
this.make = make;
this.model = model;
this.year = year;
};
Car.prototype = {
constructor : Car,
getMake : function(){
return this.make;
},
getModel : function(){
return this.model;
},
getYear : function(){
return this.year;
}
};
// 工厂模式(闭包工厂)
var CarFactory = (function(){
// 用于承装已经生产好的car
var createCars = {};
return {
createCar : function(make, model, year){
// 如果createCars对象里已经存在了当前的make, model, year
if(createCars[make+model+year]){
return createCars[make+model+year];
}else{
var car = new Car(make, model, year);
createCars[make+model+year] = car;
return car;
}
}
};
})();
// 单体模式(外在数据 和 内在数据 结合在一起)
var CarRecordManager = (function(){
// 把登记好的汽车放到这个对象里
var carRecordDataBase = {};
return {
addCarRecord : function(make, model, year, owner, tag, renewDate){
var car = CarFactory.createCar(make, model, year);
carRecordDataBase[tag] = {
owner : owner,
renewDate : renewDate,
car : car
};
},
renewRegistration :function(tag, newRenewDate){
carRecordDataBase[tag].renewDate = newRenewDate;
}
};
})();
// 享元模式的测试
var arr = [];
var stime = new Date().getTime();
for(var i = 0; i < 5000000;i++){
arr.push(CarRecordManager.addCarRecord('上海大众', '辉腾', '2017-06-09', 'Jagger', '浙A10086', '2017-07-01'));
}
var etime = new Date().getTime();
alert(etime - stime);
// 运行时间 3.5s; 内存占用 71M;
// 我们对比一下,内存占用大大减小了