享元模式(Flyweight)
运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销。
分页功能:类似公交车向前一站一站的传递
<ul id="container"></ul>
<button id="next_page">下一页</button>
/**
* 享元模式
*/
var Flyweight = (function () {
// 存储已创建的元素
var created = [];
// 创建一个列表容器
function create() {
const container = document.getElementById('container');
const item = document.createElement('li');
container.appendChild(item);
// 缓存新创建的元素
created.push(item);
// 返回创建的新元素
return item;
}
return {
created,
// 通过数据渲染DOM
renderDomByData(pageSize) {
// 如果数据总量小于等于传入的单页最大数据量pageSize,那么创建总数居量条数据
// 默认created为空数组小于单页数据量,自动创建li
if (created.length < pageSize) {
return create();
}
// 当 created 存满 pageSize 条数据量后不再新增DOM,而是将第一个DOM放到最后一个的位置
else {
// 删除数组的第一个元素,并返回删除的元素
var li = created.shift();
created.push(li);
return li;
}
},
}
}());
// 全部数据
let list = new Array(18).fill(null).map((_t, i) => i + 1);
// 单页条数
const pageSize = 5;
// 当前页码
let pageNum = 1;
console.log(`------------第${
pageNum}页 渲染流程 开始--------------`);
// 初始化的渲染
for (let i = 0; i < pageSize; i++) {
// 通过享元类获取创建的元素并写入内容
Flyweight.renderDomByData(pageSize).innerText = list[i];
console.log(Flyweight.created.map(el => el.innerText));
}
console.log(`------------第${
pageNum}页 渲染流程 结束--------------`);
document.getElementById('next_page').onclick = function () {
if (list.length <= pageSize) return;
console.log(`------------第${
pageNum + 1}页 渲染流程 开始--------------`);
for (let i = 0; i < pageSize; i++) {
// 通过享元类获取创建的元素并写入内容
Flyweight.renderDomByData(pageSize).innerText = list[pageNum * pageSize + i] || '';
console.log(Flyweight.created.map(el => el.innerText));
}
console.log(`------------第${
pageNum + 1}页 渲染流程 结束--------------`);
pageNum++;
};
享元动作
让继承者享受元类对象上提供的属性和方法
// 享元类 - 让继承者享受元类对象上提供的属性和方法
const Movement = {
moveX: function (x) {
this.x = x;
},
moveY: function (y) {
this.y = y;
}
};
// 玩家继承运动对象
let Player = function (x, y, color) {
this.x = x;
this.y = y;
this.color = color;
}
Player.prototype = Movement;
Player.prototype.changeColor = function (color) {
this.color = color;
};
// 精灵继承运动对象
let Sprite = function(x, y, radius){
this.x = x;
this.y = y;
this.radius = radius;
}
Sprite.prototype = Movement;
Sprite.prototype.changeRadius = function(radius){
this.radius = radius;
}
享元模式特点
主要还是
对其数据、方法共享分离
,它将数据
和方法
分成内部数据
、内部方法
和外部数据
、外部方法
。内部方法与内部数据指的是相似或者共有的数据和方法,所以将这一部分提取出来减少开销,以提高性能。
就像城市里人们每天上班或者学生上学都要走一定的路。他们有的人开私家车,有的坐公交,当然我们是很容易看出坐公交在花费上要比私家车的开销少很多,主要是因为它让更多的人共有这一交通工具。