简单工厂
假设你想开一个自行车店,里面有几种不同品牌的自行车,可以用下面的类表示。
var BicycleShop = function(){};
BicycleShop.prototype ={
sellBicyle:function(model){
var bicyle ;
switch(model){
case 'The Speedster':
bicyle = new Speedster();
break;
case 'The Lowrider':
bicyle = new Lowrider();
break;
case 'The Comfort Cruiser':
default:
bicyle = new ComfortCruiser();
}
Interface.ensureImplements(bicyle,Bicyle);
bicyle.assemble();
bicyle.wash();
return bicyle;
}
}
var Bicyle = new Interface('Bicyle',['assemble','wash','ride','repair']);
var Speedster = function(){};
Speedster.prototype = {
assemble:function(){},
wash:function () {
},
ride:function () {
},
repair:function () {
}
}
var Lowrider = function(){};
Lowrider.prototype = {
assemble:function(){},
wash:function () {
},
ride:function () {
},
repair:function () {
}
}
var ComfortCruiser = function(){}
ComfortCruiser.prototype = {
assemble:function(){},
wash:function () {
},
ride:function () {
},
repair:function () {
}
}
var californiaCruisers = new BicycleShop();
// 你想买一辆The Speedster 品牌的自行车
var yourNewBike = californiaCruisers.sellBicyle('The Speedster');
console.log(yourNewBike)
关于 interface 详见https://www.jianshu.com/p/61b4467ea157
这样看起来似乎很不错,但是如果你想要新增一种品牌,就要修改BicycleShop,更好的办法是把sellBicyle转交给简单工厂:
var BicycleFactory = {
createBicycle:function(model){
var 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();
break;
}
Interface().ensureImplements(bicycle,Bicycle);
return bicycle;
}
}
var BicycleShop = function(){}
BicycleShop.prototype = {
sellBicycle:function(model){
var bicycle = new BicycleFactory(model);
bicycle.assemble();
bicycle.wash();
return bicycle;
}
}
工厂模式
真正的工厂模式与简单工厂的区别是,它不是使用另一个对象或类来创建自行车,而是使用一个子类。按照定义,工厂是将其成员对象的实例化推迟到子类中进行的类。
//这里BicycleShop 是一个抽象类
var 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');
}
}
var AcmeBicycleShop = function(){};
extend(AcmeBicycleShop,BicycleShop);
AcmeBicycleShop.prototype.createBicycle = function(model){
var 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();
break;
}
Interface.ensureImplements(bicycle,Bicycle);
return bicycle;
}
var Bicycle = new Interface('Bicyle',['assemble','wash','ride','repair']);
var AcmeSpeedster = function(){};
AcmeSpeedster.prototype = {
assemble:function(){},
wash:function () {
},
ride:function () {
},
repair:function () {
}
}
var alecsCruisers = new AcmeBicycleShop();
var yourMike = alecsCruisers.sellBicycle('The Speedster');
xhr工厂
Ajax 是现在微博开发中的一个常见任务,用于发起请求的对象是某种类的实例,具体是哪种类取决于用户的浏览器,如果代码中有多次ajax请求那么明智的做法是吧创建这种对象的代码提取到一个类中
var Ajaxhandler = new Interface('AjaxHandler',['request','createXhrObject']);
var SimpleHandler = function(){}
SimpleHandler.prototype = {
request:function(method,url,callback,postVars){
var xhr = this.createXhrObject();
xhr.onreadystatechange = function(){
if(xhr.readystate !=4){
return;
}
(xhr.status === 200)?
callback.success(xhr.responseText,xhr.responseXML):
callback.failure(xhr.status);
};
xhr.open(method,url,true);
if(method != 'POST') postVars = null;
xhr.send(postVars);
},
createXhrObject:function(){
var methods = [
function(){return new XMLHttpRequest();},
function(){return new ActiveXObject('Msxml2.XMLHTTP')},
function(){return new ActiveXObject('Microsoft.XMLHTTP')},
];
for(var i=0;i<methods.length;i++){
try {
methods[i]();
}
catch(e){
continue;
}
this.createXhrObject = methods[i](); // 之后就不用循环 检查浏览器支持的 对象了
return methods[i]();
}
throw new Error('can not create xhr');
}
}
var myHandler = new SimpleHandler();
var callback = {
scuucess:function(){},
failure:function(){}
}
myHandler.request('GET','url',callback);