工厂模式
目的:是为了创建对象
目标:
- 当创建相似对象时执行重复操作
- 当编译时不知道具体类型的情况下,为工厂客户提供一个创建对象的接口
使用场景:
- 对象的构建十分复杂
- 依赖于很多设置文件
- 需要依赖具体环境创建不同实例
- 处理大量具有相同属性的小对象
要点:
1.工厂接口是工厂方法模式的核心,与调用者直接交互用来提供产品。
2.工厂实现决定如何实例化产品,是实现扩展的途径,需要有多少种产品,就需要有多少个具体的工厂实现。
工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。
该模式使一个类的实例化延迟到了子类。
而子类可以重写接口方法以便创建的时候指定自己的对象类型。
工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。
例如 IIFE(自执行函数)
let Factory = (function(){
var FactoryModel = function(factory){
this.factory = factory;
}
return function(factory){
return new FactoryModel(factory)
}
})()
let newFactory = Factory('qqqq')
let newFactory1 =new Factory('cccc')
// let newFactory2 =new FactoryModel('ddd')//UncaughtReferenceError: FactoryModel is not defined
console.log(newFactory,newFactory1);
打印结果如下:
对象的属性的方式
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
也许可以优化成下面的这种格式,会好些:
productManager={
'createProductA':function(){
this.prd = 'A'
console.log('Product ' + this.prd);
},
'createProductB':function(){
this.prd = 'B'
console.log('Product ' + this.prd);
},
'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')
let corollaDrive = corolla.drive()
console.log(corollaDrive)// "I have 4 doors!"
---------------------
什么时候不该用工厂模式?
不滥用运用工厂模式,有时候仅仅只是给代码增加了不必要的复杂度,同时使得测试难以运行下去。
参考:
https://segmentfault.com/a/1190000012422198
https://segmentfault.com/a/1190000005133481