JS 工廠模式

1. 簡介

工廠模式的目的是爲了建立對象,它一般在類或者類的靜態方法中實現,具備如下目標:html

  • 當建立類似對象時執行重複操做
  • 當編譯時不知道具體類型的狀況下,爲工廠客戶提供一個建立對象的接口

與建立型模式相似,工廠模式建立對象(視爲工廠裏的產品)時無需指定建立對象的具體類。前端

工廠模式定義一個用於建立對象的接口,這個接口由子類決定實例化哪個類。該模式使一個類的實例化延遲到了子類。而子類能夠重寫接口方法以便建立的時候指定本身的對象類型。segmentfault

這個模式十分有用,尤爲是建立對象的流程賦值的時候,好比依賴於不少設置文件等。而且,你會常常在程序裏看到工廠方法,用於讓子類類定義須要建立的對象類型。設計模式

2. 實現

一個簡單的實現,使用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!"

3. 總結

那麼何時使用工廠模式呢,如下幾種情景下工廠模式特別有用:測試

  • 對象的構建十分複雜
  • 須要依賴具體環境建立不一樣實例
  • 處理大量具備相同屬性的小對象

何時不應用工廠模式:
不濫用運用工廠模式,有時候僅僅只是給代碼增長了沒必要要的複雜度,同時使得測試難以運行下去。this


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

  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系列(28):設計模式之工廠模式
《JS 模式》
《Javascript 設計模式》 - 張榮銘

PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~

另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~

相關文章
相關標籤/搜索