简单工厂模式
//用工厂判断创建哪个对象,主要用于同一类对象的创建
var a = function(){}
var b = function(){}
var c = function(){}
var k = function(name){ //工厂
switch(name){
case 'a':
return new a();
case 'b':
return new b();
case 'c':
return new c();
}
}
var k1 = k('a')
//如果几个对象中有很多相同之处的话,可以提出来,用下面的方法
//下面的方法和寄生继承很像,不同的是没有继承上面方法
function aa(name){
var o = new Object() //创建一个对象,并扩展其属性和功能
o.a = 1;
o.show = function(){};
//上面是相同的属性功能,下面的根据name不同的
if(name === 'a'){
//...
}else if(name === 'b'){
//...
}
return o;
}
var kk1 = aa('a')
//上面两种方法前者通过实例化对象创建,第二个通过对新对象的包装增强属性功能
//前者如果这些类继承同一父类,那么父类原型的方法是可以共用的
//而后者寄生方式创建的对象都是新个体,方法不能共用
工厂方法模式
//通过对类的抽象使创建业务主要用于创建多类产品的实例
//简单工厂模式有个问题,当类多时,每次都需要修改两处(增加新的类,以及case里增加)
//为解决这个问题,可以:
var f = function(type, content){
if(this instanceof f){ //安全的工厂方法,防止忘记写new
var s = new this[type](content)
return s
}else{
return new f(type, content)
}
}
f.prototype = {
a: function(content){},
b: function(content){}
}
//这样每次添加只要在原型中添加一个类即可
//比如这里就是new出构造函数a
var k = new f('a', 1);
抽象工厂模式
//抽象类
var car = function(){};
car.prototype = {
getPrice: function(){
return new Error('抽象方法不能调用');
}
}
//创建了一个没有任何属性,原型方法不能调用的类,但在继承上却有用。继承时一些方法需要子类重写,若子类没有重写,就会从父类继承,这时在父类抛出错误可以让我们知道忘记了重写。
//抽象类中定义的方法只是显示的定义了些功能,没有具体实现,不能用来创建真实的对象,一般用来作为父类创建子类。
var vf = function(a, b){
//判断抽象工厂中是否有该抽象类
if(typeof vf[b] === 'function'){
function F(){}; //缓存类
F.prototype = new vf[b](); //继承父类的属性和方法
a.constructor = a; //将子类的constructor指向子类
a.prototype = new F(); //子类原型继承'父类'
}else{
throw new Error('未创建该抽象类'); //不存在该抽象类抛出错误
}
}
//抽象类
vf.a = function(){
this.type = 'a';
}
vf.a.prototype = {
aaa: function(){
return new Error('抽象方法不可调用');
}
}
vf.b = function(){
this.type = 'b';
}
vf.b.prototype = {
bbb: function(){
return new Error('抽象方法不可调用');
}
}
//创建子类abc
var abc = function(price){
this.price = price;
}
vf(abc, 'a'); //实现对a抽象类的继承
abc.prototype.aaa = function(){};
var x = new abc();
//创建子类abc2
var abc2 = function(price){
this.price = price;
}
vf(abc2, 'b'); //实现对b抽象类的继承
abc2.prototype.bbb = function(){};
var x2 = new abc2();
//抽象工厂其实是一个类似子类继承父类的方法,在抽象工厂中判断抽象类是否存在,存在则继承父类的方法
//对过渡类的原型继承时不仅需要继承父类原型的方法,还要继承父类的对象属性,所以需要new将父类构造函数执行一遍来复制其中的属性和方法
//用这种方法就知道子类属于哪个产品簇,比如这里abc属于a,abc2属于b,之后还有abc3、abc4的话也可以知道属于a还是b,同时也就知道了对应的该产品簇需要的方法并正确使用
上面的继承方法,两次new abc()时,会出现引用类型相互影响的情况。
找网上的抽象工厂模式,都是用上面的继承方法,为了不造成影响,应该使用寄生组合式继承。
林秀栋的技术博客