JS 建造者模式

SHERlocked93發表於2017-12-14

1. 簡介

在軟體系統中,有時候面臨著“一個複雜物件”的建立工作,其通常由各個部分的子物件用一定的演算法構成;由於需求的變化,這個複雜物件的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的演算法確相對穩定。如何應對這種變化?如何提供一種“封裝機制”來隔離出“複雜物件的各個部分”的變化,從而保持系統中的“穩定構建演算法”不隨著需求改變而改變?這就是要說的建造者模式。

建造者模式(Builder pattern),將一個複雜物件的構建層與其表示層相互分離,使得同樣的構建過程可以採用不同的表示。也就是說如果我們用了建造者模式,那麼使用者就需要指定需要建造的型別就可以得到它們,而具體建造的過程和細節就不需要知道了。

在工廠模式中,對建立的結果都是一個完整的個體,我們對參見的過程不為所知,只瞭解建立的結果物件。而在建造者模式中我們關心的是物件的建立過程,因此我們通常將建立物件的類模組化,這樣使被建立的類的每一個模組都可以得到靈活的運用和高質量的複用。

2. 實現

const Human = function(param) {
  this.skill = param && param.skill || '保密'
  this.hobby = param && param.hobby || '保密'
}
Human.prototype = {
  getSkill: function() {
    return this.skill
  },
  getHobby: function() {
    return this.hobby
  }
}

const Named = function(named) { 
  (function(named, that) {
    that.wholeName = named
    if (named.includes(' ')) {
      that.FirstName = named.slice(0, named.indexOf(' '))
      that.SecondeName = named.slice(named.indexOf(' '))
    }
  })(named, this)
}

const Work = function(work) {
  (function(work, that) {
    switch (work) {
      case 'code':
        that.work = '工程師'
        that.workDesc = '每天沉迷於程式設計'
        break
      case 'UE':
        that.work = '設計師'
        that.workDesc = '設計更像一種藝術'
        break
      default :
        that.work = work
        that.workDesc = '對不起,我們不清楚您所選擇職位的描述'
    }
  })(work, this)
}

Work.prototype.changeWork = function(work) {
  this.work = work
}

const Person = function(param, name, work) {    // 構造方法,不同模組使用不同建立過程
  const _person = new Human(param)
  _person.named = new Named(name)
  _person.work = new Work(work)
  return _person
}

const xiaoming = new Person({ skill: '耍帥', hobby: '裝逼' }, 'xiao ming', 'code')
xiaoming.skill    // 耍帥
xiaoming.FirstName  // xiao
xiaoming.work    // 工程師

根據建造者的定義,表相即是回撥,也就是說獲取資料以後如何顯示和處理取決於回撥函式,相應地回撥函式在處理資料的時候不需要關注是如何獲取資料的,同樣的例子也可以在jquery的ajax方法裡看到,有很多回撥函式(比如success, error回撥等),主要目的就是職責分離。

同樣再來一個jQuery的例子:$('<div class= "foo"> bar </div>'),我們只需要傳入要生成的HTML字元,而不需要關心具體的HTML物件是如何生產的。

3. 總結

建造者模式主要用於“分步驟構建一個複雜的物件”,在這其中“分步驟”是一個穩定的演算法,而複雜物件的各個部分則經常變化,其優點是:建造者模式的“加工工藝”是暴露的,這樣使得建造者模式更加靈活,並且建造者模式解耦了組裝過程和建立具體部件,使得我們不用去關心每個部件是如何組裝的。

這種方式對於整體物件類的拆分無疑增加了結構的複雜性,因此如果物件粒度很小,或者模組間的複用率很低並且變動不大,我們最好還是要建立整體物件。


本文是系列文章,可以相互參考印證,共同進步~

  1. JS 抽象工廠模式
  2. JS 工廠模式
  3. JS 建造者模式
  4. JS 原型模式
  5. JS 單例模式
  6. JS 回撥模式
  7. JS 外觀模式
  8. JS 介面卡模式
  9. JS 利用高階函式實現函式快取(備忘模式)
  10. JS 狀態模式
  11. JS 橋接模式
  12. JS 觀察者模式

網上的帖子大多深淺不一,甚至有些前後矛盾,在下的文章都是學習過程中的總結,如果發現錯誤,歡迎留言指出~

參考:
設計模式之建造者模式
《Javascript 設計模式》 - 張榮銘

相關文章