定义:
工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。
顾名思义就是,例如一个工厂,每一个人只干一件事情,最后全部的事情串起来就是一个事件,这个事件只处理一件事情,比如造车厂,从原材料到汽车生产整个过程中有很多环节,每一个环节都有一个人(团队)负责,并且这个人(团队)只做这一个环节,最后输出的产物就是一辆汽车。总之最后的效果就是多态,和类与类之间的松耦合。
常用的场景:
- 比如一些简单的js插件(就只做一件事情,而且专门做这件事)。
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
一个简单的代码栗子:
//下面生产汽车和卡车的栗子
//Car构造函数
function Car(option) {
this.doors = option.doors || 4 //汽车的属性-门的数量
this.color = option.color || 'red' //颜色
this.state = option.state || 'brand new' //现在处于什么状态
}
//Truck构造函数
function Truck(option) {
this.color = option.color || 'blue' //颜色
this.wheelSize = option.wheelSize || 'large' //轮子的大小
this.state = option.state || 'used' //状态
}
//Vehicle工厂
function VehicleFactory() {}
VehicleFactory.prototype.vehicleClass = Car
VehicleFactory.prototype.createVehicle = function(option) {
if(option.vehicleType == 'car') {
this.vehicleClass = Car
}else {
this.vehicleClass = Truck
}
return new this.vehicleClass(option)
}
//创建生成汽车的工厂实例
var carFactory = new VehicleFactory()
var car = carFactory.createVehicle({
vehicleType: 'car',
color: 'yellow',
doors: 6
})
console.log(car instanceof Car)
console.log(car)
//true
//Car {doors: 6, color: "yellow", state: "brand new"}
var movingTruck = carFactory.createVehicle({
vehicleType: 'truck',
color: 'red',
state: 'like new',
wheelSize: 'small'
})
console.log(movingTruck instanceof Truck)
console.log(movingTruck)
//true
//Truck {color: "red", state: "like new", wheelSize: "small"}
工厂模式的优缺点:
优点:
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
- 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。
- 增加新的产品等级结构:对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,不能很好地支持“开闭原则”。