1 简单工厂模式
又叫静态工厂方法,由一个工厂方法决定创建某一种产品对象类的实例,主要用来创建某一类对象
// 实例:体育商品店
var BasketBall = function(){
}
var FootBall = function() {
}
var Tennis = function() {
}
/**
* 运动工厂
*/
var SportsFactory = function(name) {
switch(name){
case "NBA":
return new BasketBall();
case "WorldCup":
return new FootBall();
case "FrenchOpen":
return new Tennis();
}
}
// 对外使用,只需要记住一个工厂方法,传对应的参数就可以获取相应的实例化对象
var basketball = SportsFactory('NBA')
backetball.name;// 获取到实例的属性
将三个类的实例化操作封装到工厂方法中,这就可以只暴露一个接口,实现得到多个类的实例,简单工厂模式主要用与创建同一类对象或者相似对象
简单工厂模式的理念就是创建对象,除了实例化不同的类,还可以创建相似对象
实例:创建很多书
function createBook(name, time, type) {
var o = new Object();
o.name = name;
o.time = time;
o.type = type;
o.getName = function() {
console.log(this.name)
}
return o;
}
var book1 = createBook("javascript 设计模式", '2019-3-26", "设计模式");
var book2 = createBook("JavaScript 权威指南", 'null', 'javascript');
个人理解
简单工厂模式的主要作用,就是将类的实例化操作提取出来,实现对某一类或者相似对象的创建。
2 工厂方法模式
前面简单工厂模式可以很快的创建同一类对象,但是每次要新增一个新类都要修改两处地方——新增构造函数和修改工厂方法。在工厂方法模式中,我们可以将不同类的实例用一个工厂方法管理起来。如下例:
// 工厂方法
var Factory = function(type, content) {
if(this instanceof Factory){
var s = new this[type](content);
return s;
} else {
return new Factory(type, content);
}
}
Factory.prototype = {
Java: function(content){
// ...
},
JavaScript: function(content){
// ...
},
UI: function(content){
// ...
}
//...
如果我要创建一个新的类,在工厂对象的prototype中添加,然后在Factory中传入正确的参数即可得到相应的实例
3 抽象工厂模式
通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建某一类产品的实例。
例:
// 抽象工厂方法,使用抽象类创建子类
var VehicleFactory = function(subType, superType) {
if(typeof VehicleFactory[superType] === 'function'){
function F(){}
F.prototype = new VehicleFactory[superType]();
subType.prototype = new F();
subType.prototype.constructor = subType;
}else{
throw new Error('未找到该抽象类')
}
}
// 小汽车抽象类
VehicleFactory.Car = function(){
this.type = 'Car'
}
VehicleFactory.Car.prototype = {
getPrice: function() {
return new Error('抽象方法不能用')
},
getSpeed: function() {
return new Error('抽象方法不能用')
}
}
从中我们可以看到,抽象工厂方法其实是子类继承父类的方法,父类是抽象类,指定了一套规则。使用抽象工厂方法,可是实现从多个抽象类扩展相应的子类。那么扩展出来的子类该怎么用呢?看下例:
// 新建子类使用抽象工厂方法
function BMW(price, speed) {
this.price = price;
this.speed = speed;
}
VehicleFactory(BMW, 'Car');
BMW.prototype.getSpeed = function() {
return this.speed;
}
BMW.prototype.getPrice = function() {
return this.price;
}
var bmw = new BMW(10000, 100);
console.log(bmw.type) // Car
console.log(bmw.getPrice()) // 10000
抽象类提供一些通用的属性和未实现的方法,通过抽象工厂方法扩展子类,子类实例化后重写抽象方法。
总结
工厂模式主要用于创建新的实例或者衍生出新的类簇,使用工厂模式的主要原因是对类的实例的构建过程进行封装,用户通过工厂方法来获取实例,而不关心实例的构建过程。