代码要写成别人看不懂的样子(八)

本篇文章参考书籍《JavaScript设计模式》–张容铭

前言

  铁汁们,我又来了,上节的组合模式,各位乱了没?不慌哈,这一节我们一起学个更乱的,就不会觉得上一个乱了。

  大家学东西肯定逃不开一个问题,性能。实现功能的方法千千万,为什么有的方法好,有的方法不合适?很大一部分原因是性能问题,性能这东西,平时不注意,爆发起来可是灾难性的,页面崩溃怕不怕,卡顿怕不怕,这些都是对用户特别不友好的问题。

  最关键的还是不好定位,不好修改,一旦出现,肯定涉及重构,解决成本太大。夫病已成而后药之,乱已成而后治之,譬犹渴而穿井,斗而铸锥,不亦晚乎?

享元模式

  主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

  举个例子,页面上展示新闻,每页 5 条,想看更多的新闻,需要翻页。这个例子就可以用到享元模式,首先需要一个操作方法。

var Flyweight = function() {
    
    
	//已创建元素
	var created = [];
	//创建一个新闻包装容器
	function creat() {
    
    
		var dom = document.creatElement('div');
		//将容器插入新闻列表容器中
		document.getElementById('container').appendChild(dom);
		//缓存新创建的元素
		created.push(dom);
		//返回创建的新元素
		return dom;
	}
	return {
    
    
		//获取创建新闻元素方法
		getDiv: function() {
    
    
			//如果已创建的元素小于当前页元素总个数,则创建
			if(created.length < 5) {
    
    
				return create();
			} else {
    
    
				//获取第一个元素,并插入最后面
				var div = created.shift();
				created.push(div);
				return div;
			}
		}
	}
}

  上面我们创建了个享元类,接下来由于每页显示 5 条,所有我们创建 5 个元素,保存在享元类内部,通过享元类的 getDiv 来获取创建的元素,享元类内部的数据和方法完成后,我们需要实现外部数据了。

var paper = 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() {
    
    
	//如果新闻不足5条,则返回
	if(article.length < 5) return;
	var n = ++paper * num % len, //获取当前页第一条新闻索引
		j = 0;
	//插入五条新闻
	for(; j < 5; j++) {
    
    
		//如果存在 n+j 条则插入
		if(article[n + j]) {
    
    
			Flyweight.getDiv().innerHTML = article[n + j];
		//否则插入起始位置第 n + j - len 条
		} else if(article[n + j - len]) {
    
    
			Flyweight.getDiv().innerHTML = article[n + j - len];
		//如果都不存在则插入空字符串
		} else {
    
    
			Flyweight.getDiv().innerHTML = '';
		}
	}
}

  通过享元模式,我们进入页面后只创建5个元素,不用每次翻页的时候,都需要重新创建了。

应用场景

  享元模式在面向对象编程中是很常见的,比如游戏当中,每个角色的移动方法,肯定都是相同的,我们就可以创建一个享元类。

var FlyWeight = {
    
    
	moveX: function(x) {
    
    
		this.x = x;
	},
	moveY: function(y) {
    
    
		this.y = y;
	}
}

  其他任何角色都可以通过继承的方式实现,比如放英雄继承移动方法。

//创建一个英雄类,继承移动方法
var Hero = function(s, y, c) {
    
    
	this.x = x;
	this.y = y;
	this.color = c;
}
Hero.prototype = FlyWeight;
Hero.prototype.changeC = function(c) {
    
    
	this.color = c;
}
//创建一个怪物类,继承移动方法
var Monster = function(x, y, r) {
    
    
	this.x = x;
	this.y = y;
	this.r = r;
}
Monster.prototype = FlyWeight;
Monster.prototype.changeR = function(r) {
    
    
	this.r = r;
}

  接下来创建实例

//创建英雄实例
var hero = new Player(5, 6, 'red')
hero.moveX(6);
hero.moveY(7);
console.log(hero); //{x: 6, y: 7, color: 'red'}

//创建怪物实例
var monster = new Player(2, 3, 4)
monster.moveX(3);
monster.moveY(4);
console.log(monster); //{x: 3, y: 4, r: 2}

  各位,本节结束,我们就介绍完了所有的结构型的设计模式,结构型的设计模式目的在将类,对象等,组合成更复杂的结构来应对需求,应用设计模式可以简化其设计方案,让复杂的结构可以变得更合理,易读懂。

  




猜你喜欢

转载自blog.csdn.net/EcbJS/article/details/109364555