工廠模式的目的是爲了建立對象,它一般在類或者類的靜態方法中實現,具備如下目標:html
與建立型模式相似,工廠模式建立對象(視爲工廠裏的產品)時無需指定建立對象的具體類。前端
工廠模式定義一個用於建立對象的接口,這個接口由子類決定實例化哪個類。該模式使一個類的實例化延遲到了子類。而子類能夠重寫接口方法以便建立的時候指定本身的對象類型。segmentfault
這個模式十分有用,尤爲是建立對象的流程賦值的時候,好比依賴於不少設置文件等。而且,你會常常在程序裏看到工廠方法,用於讓子類類定義須要建立的對象類型。設計模式
一個簡單的實現,使用IIFE:緩存
var Car = (function () { var Car = function (model, year, miles) { this.model = model; this.year = year; this.miles = miles; }; return function (model, year, miles) { return new Car(model, year, miles); }; })(); var tom = new Car("Tom", 2009, 20000); var dudu = new Car("Dudu", 2010, 5000);
若是使用對象屬性來實現:微信
var productManager = {}; productManager.createProductA = function() { this.prd = 'A' console.log('Product ' + this.prd); } productManager.createProductB = function() { this.prd = 'B' console.log('Product ' + this.prd); } productManager.factory = function(typeType) { return new productManager[typeType]; } productManager.factory("createProductA"); // Product A productManager.factory("createProductB"); // Product B
如下例子中的工廠方法接受在運行時以字符串形式指定的類型,而後建立並返回所請求類型的對象。函數
function CarMaker() {} CarMaker.prototype.drive = function() { return `I have ${this.doors} doors!` } CarMaker.factory = function(type) { const constr = type if (typeof CarMaker[constr] !== 'function') { throw new Error(`${constr} doesnot exist`) } // 原型繼承的方式使得原型繼承父類 if (typeof CarMaker[constr].prototype.drive !== 'function') { CarMaker[constr].prototype = new CarMaker() } return new CarMaker[constr]() } CarMaker.Compact = function() { this.doors = 4} CarMaker.Convertible = function() { this.doors = 2} const corolla = CarMaker.factory('Compact') corolla.drive() // "I have 4 doors!"
也能夠把實際對象的建立工做放到原型中:學習
const Factory = function(type, content) { return (this instanceof Factory) ? new this[type](content) : new Factory(type, content) } Factory.prototype.Compact = function(content) { this.doors = 4} Factory.prototype.Convertible = function(content) { this.doors = 2} Factory.prototype.Compact.prototype.drive = function() { return `I have ${this.doors} doors!` } const corolla = Factory('Compact') corolla.drive() // "I have 4 doors!"
那麼何時使用工廠模式呢,如下幾種情景下工廠模式特別有用:測試
何時不應用工廠模式:
不濫用運用工廠模式,有時候僅僅只是給代碼增長了沒必要要的複雜度,同時使得測試難以運行下去。this
本文是系列文章,能夠相互參考印證,共同進步~
網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~
參考:
深刻理解JavaScript系列(28):設計模式之工廠模式
《JS 模式》
《Javascript 設計模式》 - 張榮銘
PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~
另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~