我盡量用最少的文字,最少的篇幅末荐,講明白設(shè)計(jì)模式的方方面面。
文章連接
理解單利模式
確保只有一個(gè)實(shí)例播急,并提供全局訪問(wèn)蓖捶。
例如 redux 中的 store狠裹,線程池剪撬,全局緩存椿息,瀏覽器 window 對(duì)象等法希。
上代碼:通用的惰性單利模式
let getSingle = function(fn) {
let result = 'initial_single';
return function() {
if (result === 'initial_single') {
result = fn.apply(this, arguments);
}
return result;
}
}
// 測(cè)試 -----
let Tree = function() {
console.log('something')
}
let getSingleTree = getSingle(Tree)
getSingleTree() // 第一次調(diào)用時(shí)輸出:console.log('something')
getSingleTree() //
getSingleTree() //
// 調(diào)用三次只會(huì)輸出一次
單利模式的演進(jìn)過(guò)程
1. 普通單利
用變量來(lái)標(biāo)記某個(gè)對(duì)象是否被創(chuàng)建過(guò)枷餐,如果是直接返回之前創(chuàng)建的變量
上代碼:
let Person = function(name) {
this.name = name
}
Person.prototype.getName = function() {
console.log(this.name)
}
Person.getSingle = (function() {
let instance = null;
return function(name) {
if (!instance) {
instance = new Person(name)
}
return instance
}
})();
2. 透明單利
有一個(gè)類(lèi),不論你 new 多少次苫亦。它都給你返回第一次 new 的那個(gè)實(shí)例毛肋。這就是透明的單利模式,所謂透明屋剑,就是你不能看出它是單利村生。
上代碼:
let Person = (function() {
let instance;
Person = function(name) {
if (instance) {
return instance;
}
this.name = name;
return instance = this;
}
return Person;
})();
let p = new Person('C#')
let a = new Person('java')
console.log(p === a) // true
3. 用代理實(shí)現(xiàn)單利
之前的單利實(shí)現(xiàn)都有一個(gè)共同的問(wèn)題:類(lèi)和單利的代碼都交織在一起。這樣有違反“單一職能”原則饼丘。
代理趁桃,就是把類(lèi)應(yīng)該做的事,和單利應(yīng)該做的事情分開(kāi)
上代碼:
// 類(lèi)
var Person = function(name) {
this.name = name;
}
// 代理
let ProxySinglePerson = (function() {
let result;
return function(name) {
if (result) {
return result
}
result = new Person(name)
return result
}
})();
let p = new ProxySinglePerson('C#')
let a = new ProxySinglePerson('java')
console.log(p === a) // true
5. 惰性單利
意思是肄鸽,需要用到的時(shí)候才創(chuàng)建卫病。這是單利模式的應(yīng)用中非常重要的一點(diǎn)。
其實(shí)之前的代碼中也已經(jīng)包含了惰性單利典徘,看下面代碼蟀苛。重點(diǎn)關(guān)注“惰性”。
上代碼:
// 類(lèi)
var Person = function(name) {
this.name = name;
}
Person.getSingle = (function() {
let instance;
return function(name) {
if (!instance) {
instance = new Person(name);
}
return instance;
}
})();
var p = Person.getSingle('C#')
var a = Person.getSingle('java')
console.log(p === a) // true
6. 通用的惰性單利
一勞永逸逮诲,這次咱們完成一個(gè)通用的惰性單利帜平。也就是文章開(kāi)頭的那段代碼
let getSingle = function(fn) {
let result = 'initial_single';
return function() {
if (result === 'initial_single') {
result = fn.apply(this, arguments);
}
return result;
}
}
小結(jié)
本章學(xué)習(xí)了單利模式的演進(jìn)過(guò)程,還提到了代理模式和單一職責(zé)原則梅鹦。之后的文章里我會(huì)對(duì)他們做詳細(xì)的講解裆甩。
在 getSingle 函數(shù)中,也提到了閉包和高階函數(shù)的概念齐唆。單利模式是一種非常實(shí)用的模式嗤栓,特別是惰性單利技術(shù),在合適的時(shí)候才創(chuàng)建對(duì)象,并且全局唯一茉帅。更奇妙的是創(chuàng)建對(duì)象和管理單利的職責(zé)被分布在兩個(gè)不同的方法中叨叙,這兩個(gè)方法組合起來(lái)才有單利模式的威力。