工厂设计模式
工厂设计模式, 顾名思义就是生产对象的工厂, 在这里需要注意的是生产的对象都是同一规格的, 具有某些相同的特性, 否则工厂模式的意义荡然无存
接口在工厂模式中有着重要的作用, 如果对生产的对象不实现某个接口, 试问我们为什么还要工厂模式, 工厂模式使得我们创建的所有事例可以一视同仁, 屏蔽了不同对象的区别, 因为他们实现的同样的接口
简单工厂
简单工厂就是工厂所生产的产品虽然都符合接口规范, 但产品无法分类, 这里简单举一个商店出售自行车的例子, 则所生产的自行车都实现了自行车的规范, 但自行车无法分辨厂家
let BicycleShop = (function () {
/* BicycleFactory namespace. */
let BicycleFactory = {
createBicycle: function(model) {
let bicycle;
switch(model) {
case 'The Speedster':
bicycle = new Speedster();
break;
case 'The Lowrider':
bicycle = new Lowrider();
break;
case 'The Comfort Cruiser':
default:
bicycle = new ComfortCruiser();
}
Interface.ensureImplements(bicycle, Bicycle);
return bicycle;
}
};
/* BicycleShop class, improved. */
let BicycleShop = function() {};
BicycleShop.prototype = {
sellBicycle: function(model) {
var bicycle = BicycleFactory.createBicycle(model);
bicycle.assemble();
bicycle.wash();
return bicycle;
}
};
return BicycleShop;
})();
/* The Bicycle interface. */
var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'ride', 'repair']);
/* Speedster class. */
var Speedster = function() { // implements Bicycle
...
};
Speedster.prototype = {
assemble: function() {
...
},
wash: function() {
...
},
ride: function() {
...
},
repair: function() {
...
}
};
/* Usage. */
var californiaCruisers = new BicycleShop();
var yourNewBike = californiaCruisers.sellBicycle('The Speedster');
简单工厂的弊端在于所有的对象都有工厂类来实现, 无法对对象分类, 降低了拓展性, 比如如果有膜拜自行车专卖店和ofo自行车专卖店呢, 所以简单的业务简单工厂就够了, 如果面对复杂业务逻辑则需要抽象工厂模式
抽象工厂
真正的工厂模式与简单工厂区别在于, 它不是使用工厂类来生产对象的, 而是使用其子类, 将其成员对象的实例化推迟到子类中, 这样就可以对自行车进行分类, 例如工厂类为接口或抽象类, 膜拜自行车工厂和ofo自行车工厂为子类, 当然这两家的自行车都实现了自行车接口, 下面如图所示;
首先定义一个工厂类
var BicycleShop = (function() {
let BicycleShop = function() {};
BicycleShop.prototype = {
sellBicycle: function(model) {
var bicycle = this.createBicycle(model);
return bicycle;
},
createBicycle: function(model) {
throw new Error('Unsupported operation on an abstract class.');
}
};
return BicycleShop
})();
然后定义多个继承工厂类的基于分类的类
let AcmeBicycleShop = (function() {
/* AcmeBicycleShop class. */
let AcmeBicycleShop = function() {};
extend(AcmeBicycleShop, BicycleShop);
AcmeBicycleShop.prototype.createBicycle = function(model) {
let bicycle;
switch(model) {
case 'The Speedster':
bicycle = new AcmeSpeedster();
break;
case 'The Lowrider':
bicycle = new AcmeLowrider();
break;
case 'The Flatlander':
bicycle = new AcmeFlatlander();
break;
case 'The Comfort Cruiser':
default:
bicycle = new AcmeComfortCruiser();
}
Interface.ensureImplements(bicycle, Bicycle);
return bicycle;
};
return AcmeBicycleShop
})();
var GeneralProductsBicycleShop = (function() {
/* GeneralProductsBicycleShop class. */
let GeneralProductsBicycleShop = function() {};
extend(GeneralProductsBicycleShop, BicycleShop);
GeneralProductsBicycleShop.prototype.createBicycle = function(model) {
let bicycle;
switch(model) {
case 'The Speedster':
bicycle = new GeneralProductsSpeedster();
break;
case 'The Lowrider':
bicycle = new GeneralProductsLowrider();
break;
case 'The Flatlander':
bicycle = new GeneralProductsFlatlander();
break;
case 'The Comfort Cruiser':
default:
bicycle = new GeneralProductsComfortCruiser();
}
Interface.ensureImplements(bicycle, Bicycle);
return bicycle;
};
})();
最后使用
/* Usage. */
var alecsCruisers = new AcmeBicycleShop();
var yourNewBike = alecsCruisers.sellBicycle('The Lowrider');
var bobsCruisers = new GeneralProductsBicycleShop();
var yourSecondNewBike = bobsCruisers.sellBicycle('The Lowrider');
抽象工厂模式可以把公共代码放在父类中, 个体性的代码放在子类中, 责任分离的同时提高拓展性
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。