1、模式定义
享元模式,运用共享技术,有效地支持大量的细粒度的对象,以避免对象之间拥有相同内容而造成多余的性能开销。
享元模式,可以解决冗余结构对程序性能造成严重影响的问题。所谓享元模式,主要是对数据、方法的共享进行分离。它把数据和方法划分成内部数据、外部数据、内部方法和外部方法。内部数据和内部方法是相似的或者共有的,把内部数据和内部方法提取出来,进而减少性能开销。
2、生活中的享元模式
比如100个人从同一个起点出去,去往同一个目的地。如果这100个人都独自开车去,则每个人需要花费100元。但是,如果这100个人选择乘坐一辆巴士去,则每个人只需花费5元。这其中就蕴含着享元模式的设计思想。
3、享元模式 举例
现有一个新闻列表的页面,每页显示5条新闻。当点击页面中的“下一页”时,即实现新闻列表的翻页功能。在这个需求中,我们知道,每次翻页,页面结构中变化的只是新闻元素(如新闻标题、时间、图片等),但新闻的容器盒子是没有变化的。
下面示例中,我们就使用享元模式的思想来实现,即每次翻页时,我们不重新创建新闻的容器,而只重新创建新闻列表中发生了变化的元素。这样即可提升程序的性能。
// 享元模式
var FlyWeight = function() {
// 已创建的元素
var created = [];
// 创建一个新闻容器
function create() {
var dom = document.createElement('div'); // 一条新闻的容器
document.getElementById('page').appendChild(dom);
// 缓存新创建的元素
created.push(dom);
return dom;
}
return {
// 获取新闻元素
getDiv: function() {
// 每页显示5条新闻
if (created.length < 5) {
return create();
} else {
// 获取第一个元素,并插入至最后
var div = created.shift();
created.push(div);
return div;
}
}
}
}();
// 使用上述封装的享元模式,实现需求
var page = 0, num = 5, len = article.length;
// 添加5条新闻
for (var i = 0; i<5; i++) {
if (article[i]) {
// 只更新内容,不重新创建容器
FlyWeight.getDiv().innerHTML = article[i];
}
}
// 给“下一页”按钮绑定翻页事件
document.getElementById('next-page').onclick = function() {
if (article.length < 5) {
return;
}
// 获取当前页的第一条新闻索引
var n = ++page * num % len;
// 插入5条新闻
for (var j = 0; j<5; j++) {
if (article[n+j]) {
FlyWeight.getDiv().innerHTML = article[n+j];
} else if (article[n+j-len]) {
FlyWeight.getDiv().innerHTML = article[n+j-len];
} else {
FlyWeight.getDiv().innerHTML = "";
}
}
}
使用享元模式对页面进行优化后,每次翻页所需要操作并更新的DOM元素数据达到了最小化。这便是对程序性能的提升。
图例4、享元模式 再举例
var FlyWeight = {
moveX: function(x) {
this.x = x;
},
moveY: function(y) {
this.y = y;
}
}
var Player = function(x, y, color) {
this.x = x;
this.y = y;
this.color = color;
}
Player.prototype = FlyWeight;
Player.prototype.changeColor = function(color) {
this.color = color;
}
// 让精灵继承移动的方法
var Spirit = function(x, y, r) {
this.x = x;
this.y = y;
this.r = r;
}
Spirit.prototype = FlyWeight;
Spirit.prototype.changeR = function(r) {
this.r = r;
}
像这样把子类中相似的数据或方法提取出来,以减少子类重写时造成的额外开销。这也是享元模式的设计思想。
5、小结
享元模式把共有的数据和方法提取出来,目的是为了提高程序的执行效率,进一步提升系统的性能。享元模式有助于减少内存消耗,在大型系统开发中应用非常广泛。当然在一些小型的程序中,性能和内存的消耗对程序执行的影响不大时,如果强行使用享元模式则会导致代码逻辑变得复杂,往往会收到负效应。
本章结束 2019-02-27
网友评论