工厂模式的目的是为了建立对象,它一般在类或者类的静态方法中实现,具备如下目标: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:欢迎你们关注个人公众号【前端下午茶】,一块儿加油吧~
另外能够加入「前端下午茶交流群」微信群,长按识别下面二维码便可加我好友,备注加群,我拉你入群~