javascript設計模式一: 單例模式

20170405發表於2020-08-11

  var Singleton = function(name){

  this.name = name

  }

  Singleton.prototype.getName = function(){

  console.log(this.name);

  }

  Singleton.getInstance = (function(){ //注意這裡的getInstance方法是靜態方法

  var instance = null

  //這裡使用閉包,作用在於只有當呼叫到getInstance方法時才進行單例控制,這是一種惰性單例模式,相比標準單例中將instance變數放在Singleton建構函式中效能更好

  return function(){

  if(!instance){

  instance = new Singleton(name)

  }

  return instance

  }

  })

  var a = Singleton.getInstance('nitx')

  var b = Singleton.getInstance('sxm')

  console.log(a === b); //true

  上述透過Singleton.getInstance來獲取Singleton類的唯一物件,這種方法相對簡單,但有個問題,增加了類的不透明性,Singleton類的使用者必須知道這是一個單例類,跟以往透過new XXX的方式來獲取物件例項不同,這裡需要使用Singleton.getInstance來獲取物件。這種寫法意義不大。

  //方法二

  //透明的單例模式,使用者從這個類中建立物件時,可以像使用其他任何普通類一樣,透過new建立類例項。下面單例類的作用是在頁面中建立唯一的div節點。

  var CreateDivWrap = (function(){

  var instance = null;

  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 c = new CreateDivWrap('nitx')

  var d = new CreateDivWrap('sxm')

  console.log(c === d); //true

  上述程式碼中,還有一個缺點,為了把instance封裝起來,使用了自執行匿名函式和閉包,並且讓這個匿名函式返回真正的Singleton構造方法CreateDiv,這增加程式複雜度,CreateDiv方法負責兩件事,一件是建立物件和執行初始化init方法,第二是保證只有一個物件,這種操作違背“單一職責原則”,假如將來要利用這個類在頁面中建立多個類,也就是讓這個類從單例類變成普通類,那就得改寫CreateDivWrap建構函式,去掉控制唯一物件的那一段程式碼,麻煩!解決這個問題的方法是使用 代理實現單例模式

  //方法三:

  //先建立普通類,作用是建立div

  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)

  }

  //建立並引用代理類ProxySingletonCreateDiv,其作用是控制CreateDiv類建立唯一物件

  var ProxySingletonCreateDiv = (function(){

  var instance = null

  return function(html){

  if(!instance){

  instance = new CreateDiv(html)

  }

  return instance

  }

  })()

  var e = new ProxySingletonCreateDiv('nitx')

  var f = new ProxySingletonCreateDiv('sxm')

  console.log(e === f);

  透過引入代理類的方式,同樣完成一個單例模式的編寫,但和之前方法一、二相比,把負責管理單例的邏輯移到了代理類ProxySingletonCreateDiv中,這樣CreateDiv就是一個普通類,CreateDiv類和ProxySingletonCreateDiv類組合起來就是一個單例類。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69979119/viewspace-2710790/,如需轉載,請註明出處,否則將追究法律責任。

相關文章