什麼是單例模式 單例模式 (Singleton Pattern)又稱為單體模式,保證一個類只有一個實例,並提供一個訪問它的全局訪問點。也就是說,第二次使用同一個類創建新對象的時候,應該得到與第一次創建的對象完全相同的對象。 簡單的說就是保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,這樣的模式 ...
什麼是單例模式
單例模式 (Singleton Pattern)又稱為單體模式,保證一個類只有一個實例,並提供一個訪問它的全局訪問點。也就是說,第二次使用同一個類創建新對象的時候,應該得到與第一次創建的對象完全相同的對象。
簡單的說就是保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,這樣的模式就叫做單例模式。
單例模式的實現思路
現在我們先不考慮單例模式的應用場景,單看它的實現,思考這樣一個問題:如何才能保證一個類僅有一個實例?
一般情況下,當我們創建了一個類(本質是構造函數)後,可以通過new關鍵字調用構造函數可以生成任意多的實例對象,像這樣:
class Single {
show() {
console.log('我是一個單例對象')
}
}
const s1 = new Single()
const s2 = new Single()
// false
s1 === s2
先 new 了一個 s1,又 new 了一個 s2,很明顯 s1 和 s2 之間沒有任何瓜葛,兩者是相互獨立的對象,各占一塊記憶體空間。而單例模式想要做到的是,不管我們嘗試去創建多少次,它都只給你返回第一次所創建的那唯一的一個實例。
要做到這一點,就需要構造函數具備判斷自己是否已經創建過一個實例的能力,那麼只要用一個變數保存創建的實例,後面判斷這個變數即可。
js實現
// es6
class SingletonApple {
static instance = null;
constructor(name, creator, products) {
this.name = name;
this.creator = creator;
this.products = products;
if (!SingletonApple.instance) {
SingletonApple.instance = this;
}
return SingletonApple.instance;
}
//靜態方法
static getInstance(name, creator, products) {
if (!this.instance) {
this.instance = new SingletonApple(name, creator, products);
}
return this.instance;
}
}
console.log(SingletonApple.instance);
let ss = new SingletonApple("蘋果公司", "阿輝",
["iPhone", "iMac", "iPad", "iPod"]);
console.log(ss);
console.log(ss === SingletonApple.instance);
let appleCompany = SingletonApple.getInstance("蘋果公司", "喬布斯", [
"iPhone",
"iMac",
"iPad",
"iPod"
]);
let copyApple = SingletonApple.getInstance("蘋果公司", "阿輝", [
"iPhone",
"iMac",
"iPad",
"iPod"
]);
console.log(appleCompany === copyApple); //true
// 閉包-通過自執行函數創建閉包變數
const Singleton = (function () {
const SingleClass = function (name, creator, products) {
this.name = name;
this.creator = creator;
this.products = products;
};
let instance = null;
return function (name, creator, products) {
if (!instance) {
// 如果不存在 則new一個
instance = new SingleClass(name, creator, products)
}
return instance;
}
})()
let s1 = new Singleton("單例1", "阿輝1", [
"iPhone",
"iMac",
"iPad",
"iPod"])
let s2 = new Singleton("單例2", "阿輝2", [
"iPhone",
"iMac",
"iPad",
"iPod"])
console.log(s1 === s2)
console.log(s1)
註意點
- 確保只有一個實例
- 並提供全局訪問