經 常一個類或者一個對象都會包含其它的對象,當這些成員對象需要創建時,通常會使用 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);