設計模式填坑系列,緊接前文(距離上次寫筆記又過去了一個多月,我也不知道怎麼加班加着加着就一個月了-_-!)設計模式
工廠模式是指提供一個建立對象的接口而不保留具體的建立邏輯,能夠根據輸入類型建立對象。讓子類自行決定實例化哪種工廠類,實際的建立對象過程在子類中進行。在建立類似子類的時候,執行重複操做。(以爲我說的太抽象不要緊,立刻就到舉例子環節)函數
前面的描述可能仍是稍顯抽象,舉個遊戲裏面的例子,咱們須要實現一個生產遊戲角色的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 = "治療" }
以上代碼比較簡單,來回顧下前文說道的幾個特色:設計
實際上,js的Object()
函數,就很符合工廠模式的特徵:code
var n = Object(1) n.constructor === Number var s = Object('1') n.constructor === String var b = Object(true) n.constructor === Boolean
自我感受設計模式系列因爲仍是處於學習階段,實踐經驗相對較少,因此寫起來仍是偏向於讀書筆記類,因此可能有不少地方都顯得粗糙。權當作先佔個坑,等後續有更深刻理解再回來補上。
而後慣例感謝以前的熱心讀者,尤爲是爲我指出錯誤的小夥伴。
而後依然是每次都同樣的結尾,若是內容有錯誤的地方歡迎指出;若是對你有幫助,歡迎點贊和收藏,轉載請徵得贊成後著明出處,若是有問題也歡迎私信交流,主頁添加了郵箱地址~溜了對象