javaScript设计模式探究【4】工厂模式

         前一段时间由于清明节,女朋友来中国,所以陪人家玩了几天,就没看书,有些荒废了,这几天补上吧.接下来我们会讨论一下javascript设计模式之工程模式,这篇之后,可能对于javascript设计模式的探究会告一段落,接下来还是再多学一下javascript的一些基础知识,再巩固一下.prototype(原型链),function,作用域链,javascript操作dom,bom,变量对象,this.ajax等等,还可能看看html5,css,既然选择了走web前端这条路,那就坚持吧,是金子总会发光的.好了,回到正题:工厂模式

        工厂模式适用场合:

              1.动态实现--需要创建一些用不同方式实现同一接口的对象

              2.节省设置开销--对象需要进行复杂并且彼此相关的设置

              3.小型对象组成一个大对象--创建封装许多较小对象的对象.

        实例:

             还是看例子说话吧,个人觉得工厂模式就是switch(很肤浅),就是将一些不同方式实现同一接口的方法封装成一个对象.

View Code
/* AjaxHandler interface */
var AjaxHandler = new Interface('AjaxHandler',['request','createXhrObject']);
/* SimpleHandler class */
var SimpleHandler = function(){};   //implements 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');},
            funtion(){return new ActiveXObject('Microsoft.XMLHTTP');}
        ];
        for(var i = 0,len = method.length;i<len;i++){
            try{
                methods[i]();
            }
            catch(e){
                continue;
            }
            //if we reach this point,method[i] worked.
            this.createXhrObject = method[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.');
    }
};

            这个例子中request负责执行发出请求和处理响应结果所需的一系列操作,它先创建一个XHR对象并对其进行配置,然后再发送请求.

           这个例子可以进一步扩展,把工厂模式用在两个地方,以便根据网络条件创建专门的请求对象.在创建XHR对象时已经用过了简单工厂模式,另一个工厂则用来返回各种处理器类.首先创建两个新的处理器类,QueuedHandler会在发起新的请求之前确保所有请求都已经成功处理,而OfflineHandler则会在用户处于离线状态时把请求缓存起来。

View Code
/*QueuedHandler Class */
var QueuedHandler = function(){// implements ajaxHandler
    this.queue = [];
    this.requestInProgress = false;
    this.retryDelay =5; //in seconds
};
extend(QueuedHandler, SimpleHandler);
QueueHandler.prototype.request = function(method,url,callback,postVars,override){
    if(this.requestInProgress && !override){
        this.queue.push({
            method:method,
            url:url,
            callback:callback,
            postVars:postVars
        });
    }
    else{
        this.reuqestInProgress = true;
        var xhr = this.createXhrObject();
        var that = this;
        xhr.onreadystatechange = function(){
            if(xhr.readyState !== 4)return;
            if(xhr.status == 200){
                callback.success(xhr.responseText,xhr.responseXML);
                that.advanceQueue();
            }
            else{
                callback.failure(xhr.status);
                setTimeout(function(){
                    that.request(method,url,callback,postVars,true);},
                    that.retryDelay*1000);
            }
        };
        xhr.open(method,url,true);
        if(method!=='POST')postVars = null;
        xhr.send(postVars);
    }
};
QueuedHandle.prototype.advanceQueue =funtion(){
    if(this.queue.length === 0){
        this.requestInProgress = false;
        return;
    }
    var req = this.queue.shift();
    this.request(req.method,req.url,req.callback,req.postVars,true);
};
View Code
/* offlineHandler class */
var OfflineHandler = function(){ //implements AjaxHandler
    this.storedRequests = [];
};
extend(OfflineHandler,SimpleHandler);
OfflineHandler.prototype.request = function(method,url,callback,postVars){
    if(XhrManager.isOffline()){//Sotre the requests until we are online.
        this.storedRequest.push({
            method:method,
            url:url,
            callback:callback,
            postVars:postVars
        });
    }
    else{   //call simpleHandler's request method if we are online.
        this.flushStoredReuqests();
        OfflineHandler.superclass.request(method,url,callback,postVars);
    }
};
OfflineHandler.prototype.flushStoredReuqests = function(){
    for(var i = 0,len = storedRequests.length;i<len;i++){
        var req = storedRequests[i];
        OfflineHandler.superclass.request(req.method,req.url,req.callback,req.postVars);
    }
};

          现在该用到工厂模式了,因为程序员根本不可能知道各个最终用户实际面临的网络条件,所以不可能要求他们在开发过程中选择使用哪个处理器类,而是应该有一个工厂在运行时选择最合适的类。

View Code
/* XhrManager singleton */
var XhrManager = {
    createXhrHandler:function(){
        var xhr;
        if(this.isOffline()){
            xhr = new OfflineHandler();
        }
        else if(this.isHighLatency()){
            xhr = new QueuedHanler();
        }
        else{
            xhr = new SimpleHandler();
        }
        Interface.ensureImplements(xhr,AjaxHandler);
        return xhr;
    },
    isOffline:function(){
        
    },
    isHighLatency:function(){
        
    }
};


var myHandler = XhrManager.createXhrHandler();
var callback = {
    success:function(responseText){alert('Success:'+responseText);},
    failure:function(stateCode){alert('Failure:'+statusCode);}
};
myHandler.request('GET','script.php',callback);

         使用工厂模式的主要好处在于消除对象间的耦合,通过使用工厂方法而不是new关键字及其具体类,你可以把所有实例化代码集中在一个位置,这可以大大简化更换所用的类或在运行期间动态选择所用的类的工作,在派生子类时它也提供了更大的灵活性。使用工厂模式,你可以先创建一个抽象的父类,然后再子类中创建工厂方法,从而把成员对象的实例化推迟到更专门化的子类中进行。

         工厂模式虽然好,但是也不能滥用。

          写的很简单,就不发表了。。接下来还是先看看基础的javascript语法方面的知识,巩固一下吧。

原文地址:https://www.cnblogs.com/tonylp/p/3016484.html