享元模式
享元模式
以共享的方式降低大量重复对象在内存中的开销,就叫做享元模式。
享元模式能做到共享的关键是区分内部状态和外部状态:内部状态是可以共享的对象,外部状态会随着环境的改变而改变,不可共享。
使用场景
假如有一个下围棋的小游戏,虽然围棋一共有361枚棋子,但从颜色上区分,只有黑白两种,因此,黑白棋子各有一个就足够了。
例子:
// 创建棋子的类
var Chess=function(color){
this.color=color;
}
// 落子的函数
Chess.prototype.put=function(x,y){
console.log('在['+x+','+y+']位置放了一个'+this.color+'子');
}
// 享元工厂函数
// 负责创建和管理棋子
var ChessFactory=(function(){
// 可共享的内部状态
var black=new Chess('黑'),
white=new Chess('白');
return function(color){
if(color==='黑'){
return black;
}else{
return white;
}
}
})();
// 测试
var p1=ChessFactory('黑');
p1.put(1,1);
// 输出:在[1,1]位置放了一个黑子
var p2=ChessFactory('白');
p2.put(2,2);
// 输出:在[2,2]位置放了一个白子
var p3=ChessFactory('黑');
p3.put(3,3);
// 输出:在[3,3]位置放了一个黑子
上例中可以看到,只需要两个对象便完成了创建361枚棋子的功能。
对象池技术
享元模式是对象池技术的重要实现方式。除此以外,对象池技术的应用非常广泛,在前端开发中,对象池更多的是应用在对DOM的操作上。
假如开发一个搜索功能,当搜索“世界名人”的时候,页面里出现了3条结果;当再搜索“世界名著”的时候,页面中出现了6条结果。
如果按照对象池技术的思路,第一次搜索时创建的3个DOM元素,并不会删除,而是放进对象池中备用,
如此一来,第二次搜索时,只需再创建3个DOM元素,而不是6个。
例子:
<input type="text" /> <button>查询</button>
<div></div>
// 对象池工厂函数
// 负责创建和管理元素
var ObjectPoolFactory = function () {
// 对象池
var objectPool = [];
var creat = function () {
var p =
objectPool.length === 0
// 若对象池中没有元素,则创建
? document.createElement("p")
// 若对象池中有元素,则直接使用
: objectPool.shift();
document.querySelector("div").appendChild(p);
return p;
};
// 将元素回收至对象池中
var recover = function (ele) {
objectPool.push(ele);
};
// 暴露特性函数(特指可以访问闭包的函数)
return {
creat: creat,
recover: recover,
};
};
document.querySelector("button").addEventListener("click", function () {
var domFactory = ObjectPoolFactory();
var val = document.querySelector("input[type=text]").value;
// 临时保存已创建的Dom元素
var list = [];
document.querySelector("div").innerHTML = "";
if (val === "世界名人") {
for (var item of ["爱因斯坦", "列夫托尔斯泰", "孔子"]) {
var domElement = domFactory.creat();
domElement.innerHTML = item;
list.push(domElement);
}
} else if (val === "世界名著") {
for (var item of ["复活","简爱","童年","巴黎圣母院","飘","红与黑"]) {
var domElement = domFactory.creat();
domElement.innerHTML = item;
list.push(domElement);
}
}
for (var domItem of list) {
domFactory.recover(domItem);
}
});
如有错误,欢迎指正,本人不胜感激。
点击查看更多内容
1人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦