设计模式是:在软件设计过程当中针对「特定」问题的「简洁而优雅」的解决方案。javascript
在软件开发的历史中,沉淀了一些好的软件设计,而设计模式即是给这些好设计取了个名字。「好的设计」并非某人发明的。一个稍有经验的程序员也许在不知不觉中数次使用过这些设计模式。前端
设计模式的意义是让人们写出可复用和可维护性高的程序。java
举个例子,假设有一个空房间,咱们要日复一日地往里面放一些东西。最简单的办法固然是把这些东西直接扔进去,可是时间久了,就会发现很难从这个房子里找到本身想要的东西,要调整某几样东西的位置也不容易。程序员
因此在房间里作一些柜子也许是个更好的选择,虽然柜子会增长咱们的成本,但它能够在维护阶段为咱们带来好处。使用这些柜子存放东西的规则,或许就是一种模式。设计模式
全部设计模式的实现都遵循一条原则,即「找出程序中变化的地方,并将变化封装起来」。浏览器
一个程序的设计老是能够分为可变的部分和不变的部分。当咱们找出可变的部分,而且把这些部分封装起来,那么剩下的就是不变和稳定的部分。这些不变和稳定的部分是很是容易复用的。缓存
熟悉这些模式的程序员,对某些模式的理解也造成了条件反射,当合适的场景出现时,他们能够很快地找到某种模式做为解决方案。闭包
咱们主要学习如下模式:app
单例模式的定义是:「保证仅有一个实例,并提供一个访问它的全局访问点」。dom
单例模式是一种经常使用的模式,有一些对象咱们每每只须要一个,好比全局缓存、浏览器中的 window 对象等。
举个前端的例子,网页loading图(菊花图)。页面整个生命周期,咱们只须要生成一个loading就行了。既简化了逻辑(没必要去考虑多个请求打开了多个loading)又减小了dom的建立。
在javascript
中,函数是一等公民,因此例子我都优先使用函数来实现(原书是以面向对象的形式展示)
function generateInstance() { return { say() { console.log('hello') } } } let single = (function() { let instance // 哨兵变量 return function getSingle() { if (!instance) { // 若是尚未生成实例,那么生成一个。 instance = generateInstance() } return instance } })() let a = single() let b = single() console.log(a === b) // true
以上就是一个单例的例子了。
咱们利用闭包保存了一个哨兵变量,用来判断单例是否生成。
下面是一个生成单例的高阶函数。
var getSingle = function(fn) { var result return function() { return result || (result = fn.apply(this, arguments)) } } // 用法 let singeName = getSingle(() => `hello ${Math.random()}`) let a = singeName() let b = singeName() console.log(a === b) // true