一個(gè)類(lèi)或?qū)ο笾型▌e的對(duì)象京景。在創(chuàng)建這種成員對(duì)象時(shí)缤灵,你可能習(xí)慣于使用常規(guī)方式怠蹂,即用new關(guān)鍵字和類(lèi)構(gòu)造函數(shù)虐唠。問(wèn)題是這樣會(huì)導(dǎo)致兩個(gè)類(lèi)之間產(chǎn)生依賴(lài)性搀愧。通過(guò)工廠模式可以消除類(lèi)之間的依賴(lài)關(guān)系,他使用一個(gè)方法來(lái)決定究竟要實(shí)例化哪個(gè)類(lèi)疆偿。參照上圖那本書(shū)咱筛,第7章內(nèi)容
XHR工廠
var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXhrObject']);
/* SimpleHandler class. */
var SimpleHandler = function() {}; // implements AjaxHandler
SimpleHandler.prototype = {
//request函數(shù)負(fù)責(zé)執(zhí)行發(fā)出的請(qǐng)求和處理相應(yīng)結(jié)果所需的一系列操作
//他先使用createXhrObject()函數(shù)并對(duì)其進(jìn)行配置,然后發(fā)送請(qǐng)求
request: function(method, url, callback, postVars) {
//首次運(yùn)行或者是沒(méi)有獲得XHR對(duì)象時(shí)執(zhí)行具體的方法杆故。
//一旦獲取了XHR對(duì)象迅箩,就會(huì)緩存起來(lái),后續(xù)執(zhí)行直接從變量引用中獲取XHR對(duì)象
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()這個(gè)工廠方法根據(jù)當(dāng)前具體環(huán)境返回一個(gè)XHR對(duì)象
//首次執(zhí)行時(shí)处铛,他會(huì)依次嘗試執(zhí)行三種用于創(chuàng)建XHR對(duì)象的方法饲趋,一旦遇到
//管用的拐揭,他就會(huì)返回所創(chuàng)建的對(duì)象,同時(shí)把自己也改為返回的那個(gè)對(duì)象
createXhrObject: function() { //工廠方法.
var methods = [//三種創(chuàng)建XHR對(duì)象的方法組成數(shù)組
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
];
//下面遍歷數(shù)組方法奕塑,嘗試獲得XHR對(duì)象
for(var i = 0, len = methods.length; i < len; i++) {
try {
methods[i](); //嘗試獲得XHR對(duì)象
}
catch(e) {
continue;
}
// If we reach this point, method[i] worked.
//如果運(yùn)行到這里堂污,數(shù)組中有方法可以創(chuàng)建XHR對(duì)象
this.createXhrObject = methods[i]; //直接把對(duì)象給第一種可以獲取
//對(duì)象的方法,緩存起來(lái)
return methods[i];
}
// If we reach this point, none of the methods worked.
//如果運(yùn)行到這里龄砰,表示沒(méi)有方法可以使用盟猖,拋出錯(cuò)誤
throw new Error('SimpleHandler: Could not create an XHR object.');
}
};
/* Usage. 具體的使用方法*/
var myHandler = new SimpleHandler(); //看不到工廠化的過(guò)程
var callback = {
success: function(responseText) { alert('Success: ' + responseText); },
failure: function(statusCode) { alert('Failure: ' + statusCode); }
};
myHandler.request('GET', 'script.php', callback);
createXhrObject()這個(gè)函數(shù)就是對(duì)象工廠方法,由于需要考慮到不同瀏覽器對(duì)于ajax對(duì)象的差異性换棚,在獲取XHR對(duì)象是有根據(jù)不同的條件來(lái)進(jìn)行扒披。但是這個(gè)根據(jù)不同條件實(shí)例化XHR對(duì)象的方法
和實(shí)際的ajax請(qǐng)求方法
是兩個(gè)獨(dú)立的過(guò)程。所以在這里把實(shí)例化XHR對(duì)象的過(guò)程封裝到一個(gè)對(duì)象工廠里圃泡。在ajax方法中只需要使用XHR對(duì)象就可以了碟案。
兩個(gè)獨(dú)立的對(duì)象之間實(shí)現(xiàn)了解耦和。其實(shí)在js模式設(shè)計(jì)中每種模式基本都是圍繞功能的解耦和來(lái)展開(kāi)颇蜡。要解決問(wèn)題首先要簡(jiǎn)化問(wèn)題价说,在簡(jiǎn)化過(guò)程中才能識(shí)別出模式。