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:欢迎你们关注个人公众号【前端下午茶】,一块儿加油吧~

另外能够加入「前端下午茶交流群」微信群,长按识别下面二维码便可加我好友,备注加群,我拉你入群~

相关文章
相关标签/搜索