什麼是單例模式
單例模式,也叫單子模式,是一種常用的軟件設計模式。在應用這個模式時,單例對象的類必須保證只有一個實例存在。
單例模式的定義比較好理解,就是在應用程序中單例對象的類只有一個實例存在。
舉例說明
對於單例模式的事例,使用java
這種強類型的語言是最容易去展示的。因爲對於一個類而言,我們知道每new
一下,它就會有一個新的實例,如果要完美的保證他只有一個實例的話,那麼最好的解決方案就是讓這個類在外部無法被new
出來。讓這個類的實例只能通過這個類本身的方法來生成。
但是對於JavaScript
來說,因爲它不是一個強類型的語言,他沒有private
這種關鍵詞,所以說,他沒有辦法來限制,外部代碼通過new
關鍵字來創建實例。但是這並不影響單例模式在JavaScript
中的應用,關於單例模式的使用場景我們在本章的後面再說,還是先來看我爲大家準備的這個事例。
單例模式的例子非常簡單:全世界那麼多的人,你只有一個對吧。我們可以通過new
關鍵字來創建一個又一個的人,但他們都不是你對吧。
繪製UML類圖
這就是我繪製出來的單例模式下的UML類圖
,他只有一個類SingleObjcet
,我們給他一個名字的屬性作爲標記,然後- SingleObject()
表示這是一個私有的構造函數,不應該被new
出來,雖然我們在JavaScript
中無法防止它被new
,但是我們可以在UML類圖
中對它進行表示。getInstance()
返回一個SingleObject
實例,也就是程序中的單例對象。接下來我們通過代碼來實現一下。
代碼實現
class SingleObject {
constructor (name) {
this.name = name || '路人甲乙丙';
}
getName () {
return this.name;
}
}
SingleObject.getInstance = function () {
let instance = null;
return function () {
if (instance === null) {
instance = new SingleObject('LGD_Sunday');
}
return instance;
}
}();
const s1 = SingleObject.getInstance();
console.log(s1.getName());// LGD_Sunday
const s2 = SingleObject.getInstance();
console.log(s2.getName());// LGD_Sunday
console.log(`s1 === s2 ${s1 === s2}`); // true
const s3 = new SingleObject();
console.log(s3.getName());// 路人甲乙丙
console.log(`s1 === s3 ${s1 === s3}`); // false
在上面的代碼中SingleObject
就是我們的單例類,而SingleObject.getInstance
這個屬性方法就是SingleObject
去生成單例對象的方法。在下面的驗證代碼中,我們可以看出s1
和s2
都是同一個實例對象。同樣的我們唯一的缺陷就是無法避免s3
的創建,這是由JavaScript
語言的特性來決定的。
應用場景
在JavaScript
中,有哪些場景下使用到了單例模式?大家想一下,window
對象是不是一個單例模式?是的。window
就是在JavaScript
中的一個典型的單例模式的應用。我們在JavaScript
中的所有的全局變量變量都會被保存到window
下面,如果window
不是單例的,那麼我們整個JavaScript
的全局邏輯也就都不存在了。
除了window
之外呢?還有哪些?還有一個比較典型的例子就是:登錄用戶信息userModel
。如果大家開發過webapp
的話,那麼應該會對這個概念比較熟悉,其實所謂userModel
就是在應用全局保存的登錄用戶的信息,可以包括用戶名稱、用戶ID、用戶的購物車
等等等等。。。並且它應該是唯一的。那麼要實現這個userModel
我們應該怎麼做?一般情況下實現userModel
的方式有兩種:
window.userModel
:不過在JavaScript
的邏輯中,我們應該儘量避免污染全局變量,所以我們應該儘量不要直接把userModel
掛載到window
對象上,所以這種方式應該作爲不得已的選擇。單例模式
:我們可以通過單例模式來實現一個全局唯一的userModel
,確保我們在任何一個地方都可以獲取到唯一的登錄用戶信息,並不會污染全局空間。
總結
單例模式
在任何一個面向對象的語言中都有很重要的作用,他的主要作用是確保創建的對象在整個應用中爲唯一的。當我們需要在應用中創建具有唯一性的對象的時候,爲了避免污染全局空間,我們就可以使用單例模式。比如:userModel
、登錄框、購物車等等