js設計模式(二)-工廠模式

前言

設計模式填坑系列,緊接前文(距離上次寫筆記又過去了一個多月,我也不知道怎麼加班加着加着就一個月了-_-!)設計模式

正文

定義

工廠模式是指提供一個建立對象的接口而不保留具體的建立邏輯,能夠根據輸入類型建立對象。讓子類自行決定實例化哪種工廠類,實際的建立對象過程在子類中進行。在建立類似子類的時候,執行重複操做。(以爲我說的太抽象不要緊,立刻就到舉例子環節)函數

具體實現

前面的描述可能仍是稍顯抽象,舉個遊戲裏面的例子,咱們須要實現一個生產遊戲角色的RoleMaker工廠,達到如下目的:學習

var warrior = RoleMaker.factory('warrior')//生產一個戰士
var mage = RoleMaker.factory('mage')//生產一個法師
var priest = RoleMaker.factory('priest')//生產一個牧師
warrior.introduce()// 輸出 '我是一個戰士,個人特長是近戰'
mage.introduce()// 輸出 '我是一個法師,個人特長是魔法'
priest.introduce()// 輸出 '我是一個牧師,個人特長是治療'

在這裏,咱們能夠看到形如var warrior = RoleMaker.factory('warrior')的語句,就是使用RoleMaker工廠生產了一個戰士的過程,這裏的戰士法師牧師都是角色的一個子類。this

接下來就是如何實現上面的RoleMaker類,最核心的思想仍是原型鏈繼承(忘記的同窗請自行補課,磨刀不誤砍柴工),具體的實現代碼以下:prototype

//父類
  function RoleMaker() {
    // 這裏是父類的屬性
  }

  RoleMaker.prototype.introduce = function () {
    return '我是一個' + this.type + ',個人特長是' + this.specialty
  }

  //工廠方法
  RoleMaker.factory = function (type) {
    var role;
    // 這裏咱們直接把子類構造函數都保存在父類的靜態屬性中,這樣的好處是不污染全局命名空間,同時方便查找。實際上固然也能夠直接用`switch-case`實現
    if (typeof (RoleMaker[type]) !== "function") {
      //對未指定子類的處理,這裏是直接拋出錯誤,也能夠爲未指定類型作默認值處理
      throw {
        name: 'Error',
        message: type + 'does not exist'
      }
    }
    if (typeof (RoleMaker[type].prototype.introduce !== "function")) {
      // 判斷是否已經實現繼承,注意只繼承一次,固然因爲只是原型鏈繼承這裏判斷條件也能夠用`RoleMaker[type].constructor===RoleMaker`
      RoleMaker[type].prototype = new RoleMaker()
    }

    role = new RoleMaker[type]() //實例化,也就是實際建立對象的過程
    return role
  }

  // 每一個子類的構造函數
  RoleMaker.warrior = function () {
    this.type = "戰士",
      this.specialty = "近戰"
  }
  RoleMaker.mage = function () {
    this.type = "法師",
      this.specialty = "魔法"
  }
  RoleMaker.priest = function () {
    this.type = "牧師",
      this.specialty = "治療"
  }

以上代碼比較簡單,來回顧下前文說道的幾個特色:設計

  1. 使用者只須要知道特定子類的名稱就能夠直接生產對應的子類,無需知道具體實現邏輯
  2. 實際的建立對象過程在子類中進行
  3. 在建立類似子類的時候,執行重複操做(每一個子類只作一次的繼承)

補充一個實例

實際上,js的Object()函數,就很符合工廠模式的特徵:code

var n = Object(1)
n.constructor === Number
var s = Object('1')
n.constructor === String
var b = Object(true)
n.constructor === Boolean

小結

自我感受設計模式系列因爲仍是處於學習階段,實踐經驗相對較少,因此寫起來仍是偏向於讀書筆記類,因此可能有不少地方都顯得粗糙。權當作先佔個坑,等後續有更深刻理解再回來補上。
而後慣例感謝以前的熱心讀者,尤爲是爲我指出錯誤的小夥伴。
而後依然是每次都同樣的結尾,若是內容有錯誤的地方歡迎指出;若是對你有幫助,歡迎點贊和收藏,轉載請徵得贊成後著明出處,若是有問題也歡迎私信交流,主頁添加了郵箱地址~溜了對象

相關文章
相關標籤/搜索