对于工厂模式,其核心就是为了生产对象,实现解耦。对于js而言,一个类或对象中往往会包含别的对象,我们创建这样的成员对象时,可能习惯采用new关键字或者构造函数的方式,这样会导致两个类之间产生依赖关系,所以我们通常需要工厂模式,创建一个工厂来管理他们的实例过程,这样可以控制程序,使我们的程序更加的面向对象、多态化
简单工厂实现
对于粗粒度的工厂实现:
// 搭建一个工厂的环境
// 卖车的商店
function CarShop(){};
CarShop.prototype = {
constructor : CarShop ,
sellCar:function(type){
var car ; // 声明一个变量
switch(type){
case 'Benz': car = new Benz(); break;
case 'Bmw' : car = new Bmw(); break;
case 'Audi': car = new Audi(); break;
default: 'not buy it ';
}
//检验接口实现
BH.Interface.ensureImplements(car ,CarInterface);
return car ;
}
};
// 接口对象的实例
var CarInterface = new BH.Interface('CarInterface' ,['start','run']);
// SuperClass implements CarInterface
function BaseCar(){};
BaseCar.prototype = {
constructor:BaseCar , //为了还原实例对象.construcotr
start:function(){
alert(this.constructor.name + ' ..start');
},
run:function(){
alert(this.constructor.name + ' ..run');
}
};
// Class benz bmw audi (都是车)
// 注意关键问题:子类先继承父类 子类在扩展子类自己特有的方法
function Benz(){};
BH.extend(Benz,BaseCar); //①
Benz.prototype.driveBenz = function(){alert('Benz..drive')}; //②
//Benz.prototype.run = function(){alert('Benz..run')};
function Bmw(){};
BH.extend(Bmw,BaseCar);
Bmw.prototype.driveBmw = function(){alert('Bmw..drive')};
//Bmw.prototype.run = function(){alert('Bmw..run')};
function Audi(){};
BH.extend(Audi,BaseCar);
Audi.prototype.driveAudi = function(){alert('Audi..drive')};
//Audi.prototype.run = function(){alert('Audi..run')};
var shop = new CarShop();
var car = shop.sellCar('Benz');
car.start();
car.run();
car.driveBenz();
var car2 = shop.sellCar('Bmw');
car2.start();
car2.run();
car2.driveBmw();
//之前的继承部分代码
function extend(sub, sup) {
//让子类只继承1次父类的原型对象
var F = new Function();
//通过一个临时变量只接受父类的原型对象
F.prototype = sup.prototype;
//正常的继承
sub.prototype = new F();
//此时需要还原sub的构造函数
sub.prototype.constructor = sub;
//保存一下父类的原型对象,一方面方便解耦,另一方面方便活得父类的原型对象 见②处代码
sub.superClass = sup.prototype;
//为了确保父类的构造函数被处理过,可以加上一个保险 见①出的代码
if (sup.prototype.constructor == Object.prototype.constructor) {
//手动欢迎父类原型对象的构造器
sup.prototype.constructor = sup;
}
}
这里加入了前面所说的接口定义的方式,以及混合继承的代码。需要注意的是①②之间的顺序不能互换,见③处的代码,继承的时候会重新给子类的原型对象赋值,之前的会被覆盖掉。
进一步解耦
对于更细粒度的工厂实现,实现进一步的解耦:
// 细粒度 和 粗粒度
// 万事万物都是Object : 卖车的商店 -> 卖车 -> 生产车 -> Factory
// 搭建一个工厂的环境
// 卖车的商店
function CarShop(){};
CarShop.prototype = {
constructor : CarShop ,
sellCar:function(type){
// 销售人员...
var car = CarFactory.createCar(type);
// 保险、相关的售后服务
return car ;
}
};
//生产车的工厂 目的就是为了生产车
//单体模式
var CarFactory = {
createCar:function(type){
var car ; // 声明一个变量
switch(type){
case 'Benz': car = new Benz(); break;
case 'Bmw' : car = new Bmw(); break;
case 'Audi': car = new Audi(); break;
default: 'not buy it ';
}
//检验接口实现
BH.Interface.ensureImplements(car ,CarInterface);
return car ;
}
};
更细粒度的工厂
// 细粒度 和 粗粒度
// 万事万物都是Object:
// 你要买什么车? 去什么商店 -> 商店 -> 卖车 -> 生产车 -> Factory
// 搭建一个工厂的环境
// 卖车的商店可能有 奥迪4s店 奔驰4s店 宝马4s店
// Super Shop 卖车
// abstract Class == ? Java的抽象类 ()
/* this CarShop is a abstract */
function CarShop(){};
CarShop.prototype = {
constructor : CarShop ,
sellCar:function(type){
this.abstractSellCar(type);
} ,
abstractSellCar: function(){
throw new Error('this method is abstract...');
}
};
// Benz 4s 店
function BenzCarShop(){};
BH.extend(BenzCarShop,CarShop);
BenzCarShop.prototype = {
constructor:BenzCarShop ,
sellCar:function(type){
var car ; // 声明一个变量
var types = ['Benz']; //所有benz类型的汽车
for(t in types){
// 如果我的商店里有你想要汽车型号
if(types[t] === type){
car = CarFactory.createCar(type);
} else {
alert('没有你要的型号!');
}
}
return car ;
}
};
// 宝马 4s 店
function BmwCarShop(){};
BH.extend(BmwCarShop,CarShop);
BmwCarShop.prototype = {
constructor:BmwCarShop ,
sellCar:function(type){
var car ; // 声明一个变量
var types = ['Bmw']; //所有bmw类型的汽车
for(t in types){
// 如果我的商店里有你想要汽车型号
if(types[t] === type){
car = CarFactory.createCar(type);
} else {
alert('没有你要的型号!');
}
}
return car ;
}
};
//生产车的工厂 目的就是为了生产车
//单体模式 动态工厂模式
var CarFactory = {
createCar:function(type){
// 利用eval动态创建传入类型的实例对象
var car = eval('new '+type+'()');
//检验接口实现
BH.Interface.ensureImplements(car ,CarInterface);
return car ;
}
};
// 接口对象的实例
var CarInterface = new BH.Interface('CarInterface' ,['start','run']);
// SuperClass implements CarInterface
function BaseCar(){};
BaseCar.prototype = {
constructor:BaseCar ,
start:function(){
alert(this.constructor.name + ' ..start');
},
run:function(){
alert(this.constructor.name + ' ..run');
}
};
// Class benz bmw audi (都是车)
// 注意关键问题:子类先继承父类 子类在扩展子类自己特有的方法
function Benz(){};
BH.extend(Benz,BaseCar);
Benz.prototype.driveBenz = function(){alert('Benz..drive')};
//Benz.prototype.run = function(){alert('Benz..run')};
function Bmw(){};
BH.extend(Bmw,BaseCar);
Bmw.prototype.driveBmw = function(){alert('Bmw..drive')};
//Bmw.prototype.run = function(){alert('Bmw..run')};
function Audi(){};
BH.extend(Audi,BaseCar);
Audi.prototype.driveAudi = function(){alert('Audi..drive')};
//Audi.prototype.run = function(){alert('Audi..run')};
var shop1 = new BenzCarShop();
var car1 = shop1.sellCar('Benz');
car1.run();
var shop2 = new BmwCarShop();
var car2 = shop2.sellCar('Bmw');
car2.run();