1. 简介
工厂模式的目的是为了创建对象,它通常在类或者类的静态方法中实现,具有以下目标:
- 当创建相似对象时执行重复操作
- 当编译时不知道具体类型的情况下,为工厂客户提供一个创建对象的接口
与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。
工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。
这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于很多设置文件等。并且,你会经常在程序里看到工厂方法,用于让子类类定义需要创建的对象类型。
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. 总结
那么什么时候使用工厂模式呢,以下几种情景下工厂模式特别有用:
- 对象的构建十分复杂
- 需要依赖具体环境创建不同实例
- 处理大量具有相同属性的小对象
什么时候不该用工厂模式:
不滥用运用工厂模式,有时候仅仅只是给代码增加了不必要的复杂度,同时使得测试难以运行下去。
本文是系列文章,可以相互参考印证,共同进步~
网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~
参考:
深入理解JavaScript系列(28):设计模式之工厂模式
《JS 模式》
《Javascript 设计模式》 - 张荣铭
PS:欢迎大家关注我的公众号【前端下午茶】,一起加油吧~
另外可以加入「前端下午茶交流群」微信群,长按识别下面二维码即可加我好友,备注加群,我拉你入群~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。