经 常一个类或者一个对象都会包含其它的对象,当这些成员对象需要创建时,通常会使用 new 关键字和类的构造函数。问题是这样会创建两个类的依赖性。下面我们来看看一个模式,它能够帮助这两个类解耦,并使用一个方法来决定要创建哪个类的实例。我 们讨论简单工厂模式,它使用一个分离的类(经常是一个单态)来创建实例,还讨论比较复杂的工厂模式,使用子类来决定使用哪个具体的类来实例化一个成员对 象。
// 简单工厂
var BicycleShop = function() {};
BicycleShop.prototype = {
sellBicycle: function(model) {
var bicycle = BicycleFactory.
createBicycle(model);;
bicycle.assemble();
bicycle.wash();
return bicycle;
}
};
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 Flatlander':
bicycle = new Flatlander();
break;
case 'The Comfort Cruiser':
default:
bicycle = new ComfortCruiser();
}
Interface.ensureImplements(bicycle, Bicycle); // 确保实现接口 Bicycle
return bicycle;
}
};
var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'ride', 'repair']); // 新建一个接口,Interface 类是模仿经典 OO 中的 Interface 的实现,以后有机会再介绍这个 Interface 的实现,如果要运行实例可以把有关Interface的代码去掉
var Speedster = function() { // 实现接口 Bicycle
//
};
Speedster.prototype = {
assemble: function() {
//
},
wash: function() {
//
},
ride: function() {
//
},
repair: function() {
//
}
};
//工厂模式
var BicycleShop = function() {}; // 一个抽象类
BicycleShop.prototype = {
sellBicycle: function(model) {
var bicycle = this.
createBicycle(model);
bicycle.assemble();
bicycle.wash();
return bicycle;
},
createBicycle: function(model) {
throw new Error('Unsupported operation on an abstract class.');
}
};
以上是一个抽象类,不应该被实例化,应该通过继承来实现自行车(bicycle)的生产,工厂模式就是把成员对象的实例化延迟到他的子类,以下是一个工厂模式子类的实现:
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();
}
Interface.ensureImplements(bicycle, Bicycle);
return bicycle;
};
// 通过工厂模式来创建 XMLHTTPRequest 对象
/* AjaxHandler 接口 */
var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXhrObject']);
/* SimpleHandler 类. */
var SimpleHandler = function() {}; // 实现 AjaxHandler 接口
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() { // Factory method.
var methods = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
];
for(var i = 0, len = methods.length; i < len; i++) {
try {
methods[i]();
}
catch(e) {
continue;
}
// If we reach this point, method[i] worked.
this.createXhrObject = methods[i]; // Memoize the method.
return methods[i];
}
// If we reach this point, none of the methods worked.
throw new Error('SimpleHandler: Could not create an XHR object.');
}
};
使用实例:
var myHandler = new SimpleHandler();
var callback = {
success: function(responseText) { alert('Success: ' + responseText); },
failure: function(statusCode) { alert('Failure: ' + statusCode); }
};
myHandler.request('GET', 'script.php', callback);