傳統(tǒng)單例模式
保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
實(shí)現(xiàn)單例核心思想
無非是用一個(gè)變量來標(biāo)志當(dāng)前是否已經(jīng)為某個(gè)類創(chuàng)建過對象,如果是,則在下一次獲取該類的實(shí)例時(shí),直接返回之前創(chuàng)建的對象,接下來我們用JavaScript來強(qiáng)行實(shí)現(xiàn)這個(gè)思路,請看代碼:
var Singleton = function( name ){ this.name = name;};Singleton.prototype.getName = function(){ alert ( this.name );};Singleton.getInstance = (function(){ var instance = null; return function( name ){ if ( !instance ){ instance = new Singleton( name ); } return instance; }})();我們通過Singleton.getInstance來獲取Singleton類的唯一對象,這樣確實(shí)是沒問題的,但是js本身是沒有類這種概念的,所以我們強(qiáng)行用傳統(tǒng)單例思想來實(shí)現(xiàn)是沒有任何意義的,這樣的代碼又臭又長(其實(shí)是我自己看著不舒服嘻嘻嘻)。下面我們使用JavaScript的閉包來實(shí)現(xiàn)一個(gè)單例,請看代碼:
var CreateDiv = (function(){ var instance; var CreateDiv = function( html ){ if ( instance ){ return instance; } this.html = html; this.init(); return instance = this;};CreateDiv.prototype.init = function(){var div = document.createElement( 'div' );div.innerHTML = this.html; document.body.appendChild( div ); }; return CreateDiv; })();var a = new CreateDiv( 'sven1' ); var b = new CreateDiv( 'sven2' );alert ( a === b ); // true可以看到,這樣我們確實(shí)用閉包來實(shí)現(xiàn)了一個(gè)單例,但這個(gè)代碼還是高度耦合的,CreateDiv的構(gòu)造函數(shù)實(shí)際上負(fù)責(zé)了兩件事情。第一是創(chuàng)建對象和執(zhí)行初始化init方法,第二是保證只有一個(gè)對象。這樣的代碼是職責(zé)不明確的,現(xiàn)在我們要把這兩個(gè)工作分開,構(gòu)造函數(shù)就負(fù)責(zé)構(gòu)建對象,至于判斷是返回現(xiàn)有對象還是構(gòu)造新的對象并返回,我們交給另外一個(gè)函數(shù)去完成,其實(shí)也就是為了滿足一個(gè)編程思想:單一職責(zé)原則。這樣的代碼才能更好的解耦,請看下面代碼:
var CreateDiv = function (html) { this.html = html; this.init(); }; CreateDiv.prototype.init = function () { var div = document.createElement('div'); div.innerHTML = this.html; document.body.appendChild(div); }; var ProxySingletonCreateDiv = (function () { var instance; return function (html) { if (!instance) { instance = new CreateDiv(html); } return instance; } })(); var a = new ProxySingletonCreateDiv('sven1'); var b = new ProxySingletonCreateDiv('sven2'); alert(a === b); //true
新聞熱點(diǎn)
疑難解答
圖片精選