大数据

javascript工厂模式-XHR工厂

s3398900.jpg

一个类或对象中往往包括别的对象。在创建这种成员对象时,你可能习惯于使用常规方式,即用new关键字和类构造函数。问题是这样会导致两个类之间产生依赖性。通过工厂模式可以消除类之间的依赖关系,他使用一个方法来决定究竟要实例化哪个类。参照上图那本书,第7章内容

XHR工厂
 var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXhrObject']);

/* SimpleHandler class. */

var SimpleHandler = function() {}; // implements AjaxHandler
SimpleHandler.prototype = {
  //request函数负责执行发出的请求和处理相应结果所需的一系列操作
  //他先使用createXhrObject()函数并对其进行配置,然后发送请求
  request: function(method, url, callback, postVars) {
    //首次运行或者是没有获得XHR对象时执行具体的方法。
    //一旦获取了XHR对象,就会缓存起来,后续执行直接从变量引用中获取XHR对象
    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()这个工厂方法根据当前具体环境返回一个XHR对象
  //首次执行时,他会依次尝试执行三种用于创建XHR对象的方法,一旦遇到
  //管用的,他就会返回所创建的对象,同时把自己也改为返回的那个对象
  createXhrObject: function() { //工厂方法.
    var methods = [//三种创建XHR对象的方法组成数组
      function() { return new XMLHttpRequest(); },
      function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
      function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
    ];
    //下面遍历数组方法,尝试获得XHR对象
    for(var i = 0, len = methods.length; i < len; i++) {
      try {
        methods[i](); //尝试获得XHR对象
      }
      catch(e) {
        continue;
      }
      // If we reach this point, method[i] worked.
      //如果运行到这里,数组中有方法可以创建XHR对象
      this.createXhrObject = methods[i]; //直接把对象给第一种可以获取
//对象的方法,缓存起来      
        return methods[i];
    }

    // If we reach this point, none of the methods worked.
    //如果运行到这里,表示没有方法可以使用,抛出错误
    throw new Error('SimpleHandler: Could not create an XHR object.');
  } 
};

/* Usage. 具体的使用方法*/

var myHandler = new SimpleHandler(); //看不到工厂化的过程
var callback = { 
  success: function(responseText) { alert('Success: ' + responseText); }, 
  failure: function(statusCode) { alert('Failure: ' + statusCode); } 
};
myHandler.request('GET', 'script.php', callback);

createXhrObject()这个函数就是对象工厂方法,由于需要考虑到不同浏览器对于ajax对象的差异性,在获取XHR对象是有根据不同的条件来进行。但是这个根据不同条件实例化XHR对象的方法和实际的ajax请求方法是两个独立的过程。所以在这里把实例化XHR对象的过程封装到一个对象工厂里。在ajax方法中只需要使用XHR对象就可以了。

两个独立的对象之间实现了解耦和。其实在js模式设计中每种模式基本都是围绕功能的解耦和来展开。要解决问题首先要简化问题,在简化过程中才能识别出模式。