JS设计模式——7.工厂模式(示例-XHR)
XHR工厂
基本实现
- var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXHR']);
- var SimpleHandler = function(){};
- SimpleHandler.prototype = {
- request: function(method, url, callback, postVars){
- var xhr = this.createXHR();
- 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);
- },
- createXHR: function(){
- 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;
- }
- this.createXHR = methods[i]; //memoize the method.
- return methods[i];
- }
- }
- };
createXHR这个工厂方法根据当前的宿主环境返回适当的xhr对象.重点是createXHR在首次执行之后就被替换为了methods[i],这个就是memoizing技术了(可以称称之为记录).这样当我们下次用到createXHR的时候就不用在去能力检测了.大大的提升了性能.
SimpleHandler的调用如下:
- var myHandler = new SimpleHandler();
- var callback = {
- success: function(responseText){
- console.log('Success' + responseText);
- },
- failure: function(statusCode){
- console.log('Failure' + statusCode);
- }
- };
- myHandler.request('GET', 'stript.php', callback);
专用型连接对象
我们对上面的对象进行一个扩展,以便根据网络条件创建专门的请求对象.
首先我们先来创建两个新的处理器类:
1:QueHandler会在发起新的请求之前先确保所有请求都已经成功处理.
- var QueHandler = function(){
- this.queue = [];
- this.requestInProgress = false;
- this.retryDelay = 5;
- };
- extend(QueHandler, SimpleHandler);
- QueHandler.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.requestInProgress = true;
- var xhr = this.createXHR();
- 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);
- }
- };
- QueHandler.prototype.advanceQueue = function(){
- 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);
- };
2:OffHandler会在用户处于离线状态时把请求缓存起来.
- var OffHandler = function(){
- this.storedRequests = [];
- };
- extend(OffHandler, SimpleHandler);
- OffHandler.prototype.request = function(method, url, callback, postVars){
- if(XhrManager.isOffline()){
- this.storedRequests.push({
- method:method,
- url:url,
- callback:callback,
- postVars:postVars
- });
- }else{
- this.flushStoredRequests();
- OffHandler.superclass.request(method, url, callback, postVars);
- }
- };
- OffHandler.prototype.flushStoredRequests = function(){
- for(var i= 0, len=this.storedRequests.length; i<len; i++){
- var req = this.storedRequests[i];
- OffHandler.superclass.request(req.method, req.url, req.callback, req.postVars);
- }
- }
在运行时选择连接对象
现在该用到工厂模式了.因为程序元根本不知道各个最终用户面临的网络条件,所以要用一个工厂在运行是选择最合适的类.
- var XhrManager = {
- createXhrHandler: function(){
- var xhr;
- if(this.isOffline()){
- xhr = new OffHandler();
- }else if(this.isHighLatency()){
- xhr = new QueHandler();
- }else{
- xhr = new SimpleHandler();
- }
- Interface.ensureImplements(xhr, AjaxHandler);
- return xhr;
- },
- isOffline: function(){ //do a quick request with SimpleHandler and see if it success.
- ...
- },
- isHighLatency: function(){ //do a series of requests with SimpleHandler and time the requests,Best done once, as a branching function.
- ...
- }
- };
- var myHandler = XhrManager.createXhrHandler();
- var callback = {};
- myHandler.request('GET', 'sript.php', callback);
我只想说他的isOffline的实现亮了.
XHR的三个重要属性
JS设计模式——7.工厂模式(示例-XHR)的更多相关文章
- JS设计模式——7.工厂模式(示例-RSS阅读器)
RSS阅读器 由于我们只想跟RSS容器对象打交道,所以用一个工厂来实例化这些内部对象并把它们组装到一个RSS阅读器中. 使用工厂方法在好处在于,我们创建的RSS阅读器类不会与那些成员对象紧密耦合在一起 ...
- [JS设计模式]:工厂模式(3)
简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...
- js设计模式:工厂模式、构造函数模式、原型模式、混合模式
一.js面向对象程序 var o1 = new Object(); o1.name = "宾宾"; o1.sex = "男"; o1.a ...
- JS设计模式之工厂模式
1 什么是工厂模式? 工厂模式是用来创建对象的一种最常用的设计模式.我们不暴露创建对象的具体逻辑,而是将将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂.工厂模式根据抽象程度的不同可以分为: ...
- JS设计模式--简单工厂模式
在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工 ...
- JavaScript设计模式-10.工厂模式实例xhr
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JS设计模式——7.工厂模式(概念)
工厂模式 本章讨论两种工厂模式: 简单工厂模式 使用一个类(通常是一个单体)来生成实例. 使用场景:假设你想开几个自行车商店(创建自行车实例,组装它,清洗它,出售它),每个店都有几种型号的自行车出售. ...
- JavaScript设计模式--简单工厂模式例子---XHR工厂
第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方法不要写出Interface.prototype ,因为这是写到接 ...
- 设计模式——抽象工厂模式及java实现
设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...
随机推荐
- Mysql的两种引擎的区别
Innodb引擎概述 Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别.该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MyS ...
- 使用userData兼容IE6-10,chrome,FF 及360等浏览器的本地存储
开发过程中涉及本地存储的使用,IE很多版本都不支持localStorage,没办法,就得兼容使用userData了.废话不说了,看代码: (function(window){var LS;(funct ...
- JavaWeb基础【1】—— Tomcat
此笔记是学习黑马程序员JavaWeb系列视频的课堂笔记. 感谢黑马程序员. 一.Tomcat概述 Tomcat服务器由Apache提供,开源免费.由于Sun和其他公司参与到了Tomcat的开发中,所以 ...
- P4417 [COCI2006-2007#2] STOL
题目描述 米尔科买了一套别墅,他想要邀请尽量多的人和他一起庆祝.他需要一张大的木质矩形桌子来让他和他的嘉宾坐下.每张桌子可容纳的人数等于它的周长(四边长度的总和).米尔科想要买一张即可在他的公寓里放下 ...
- python 求两个时间差
def timeInterval(self): today = datetime.date.today() print today modifiedTime = os.stat(filename).s ...
- 命令行Scp的使用----远程拷贝文件
1.用CRT分别连上两台需要传输文件的linux系统服务器,并检查防火墙是否关闭. 查看防火墙状态: /etc/init.d/iptables status 若防火墙启用,暂时关闭防火墙: /etc/ ...
- 【BZOJ3105】【CQOI2013】新Nim游戏
Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴 ...
- 【模板】ISAP最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- CF600E Lomsat gelral 【线段树合并】
题目链接 CF600E 题解 容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可 对于每个节点合并一下两个子节点的信息 要注意叶子节点信息的合并和非叶节点信息的合并是不一样的 ...
- activity 与 service 之间的通信
activity和service通信:通过binder 举个我实际项目中的例子:在service中下载更新应用 首先是下载更新apk的service: public class UpdateVersi ...