谈谈javascript中设计模式第一篇

原创 2016年06月01日 23:36:14

最近看了一本《Javascript设计模式与开发实践》;这本书写的很不错,书中举的例子也很通俗易懂。一早就想抽点时间写写的从中的感悟,好像也拖了好久了,什么课程设计呀,考试啦。今天终于静下来了。

首先我们来谈谈满大街都是的-单例模式:
单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式虽然简单,但是在javascript这种弱类型的语言中却又着举足轻重的地位;它可以减少命名空间污染。尤其在大型的项目。十分重要。

var A={};//如果对象a是独一无二的,我们就定义了一个单例对象
A.sum=function(a,b){
    return a+b;
}
A.multiply=function(a,b){
    return a*b;
}
......

惰性单例:惰性单例指的是在需要的时候才创建对象实例。惰性单例是单例模式的重点,这种技术在实
际开发中非常有用,有用的程度可能超出了我们的想象。

Single.getInstance=(function(){
    var instance=null;
    return function(name){
        if(!instance){
            instance=new Single(name);
        }
    }
    return instance;
})();

//来一个具体的例子,生成一个遮幕,这是我们在开发中经常会遇到的。
    var createDiv=(function(){
    var div;
    return function(){
        div=document.createElement("div");
        div.style.width="100%";
        div.style.height="100%";
        div.style.zIndex="999";
        docment.body.appendChild(div);
    }
    return div;
})();

通用的惰性单例:

var getSingle = function( fn ){
    var result;
    return function(){
    return result || ( result = fn .apply(this, arguments ) );
    }
};

现在我们来说说策略模式:
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
现在有一个问题是:根据用户的等级,返回用户每个月可领取的代金券数量。

var getVoucher=function(level){
    if(level=="H"){
        return 5;
    }
    if(level=="M"){
        return 3;
    }

    if(level=="L"){
        return 1;
    }
}

可以发现,这段代码十分简单,但是存在着显而易见的缺点。

  1. getVoucher函数比较庞大,包含了很多if-else 语句,这些语句需要覆盖所有的逻辑分支
  2. getVoucher 函数缺乏弹性,如果增加了一种新等级HH,那我们必须深入getVoucher 函数的内部实现,这是违反开放-封闭原则的。
  3. 算法的复用性差,如果在程序的其他地方需要重用用户每个月可领取的代金券数量?我们的选择只有复制和粘贴。

使用策略模式重构代码

//策略类
var levelH=function(){};
levelH.prototype.count=function(){
    return 5;
}
var levelM=function(){};
levelM.prototype.count=function(){
    return 3;
}
var levelL=function(){};
levelL.prototype.count=function(){
    return 1;
}
//
 var personLevel=function(){
    this.level=null;//原始等级
}
personLevel.prototype.setLevel=function(level){
    this.level=level;//设置等级
}
personLevel.prototype.setCount=function(count){//设置策略类
    this.count=count;
}
personLevel.prototype.getCount=function(){//获取代金券数量
    return this.count.count(this.level)
}

JavaScript 版本的策略模式

var   level={
    "H":function(){
                return 5;
        },
    "M":function(){
                return 5;
        },
    "L":function(){
                return 1;
        }
}
//
var personCount=function(level){
    return level[level]();
}
console.log(personCount('H'));//输出5;

1.策略模式利用组合、委托和多态等技术和思想,可以有效地避免多重条件选择语句。
2.策略模式提供了对开放—封闭原则的完美支持,将算法封装在独立的strategy 中,使得它们易于切换,易于理解,3.易于扩展。
4.策略模式中的算法也可以复用在系统的其他地方,从而避免许多重复的复制粘贴工作。
5.在策略模式中利用组合和委托来让Context 拥有执行算法的能力,这也是继承的一种更轻便的替代方案。
当然,策略模式也有一些缺点,但这些缺点并不严重。
首先,使用策略模式会在程序中增加许多策略类或者策略对象。其次,要使用策略模式,必须了解所有的策略类。

最后我们来聊聊代理模式:
代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。
代理分为:保护代理,虚拟代理,远程代理,缓存代理等等。
保护代理用于控制不同权限的对象对目标对象的访问,但在JavaScript 并不容易实现保护代理,因为我们无法判断谁访问了某个对象。而虚拟代理是最常用的一种代理模式,下面我们主要说虚拟代理。

虚拟代理实现图片预加载:
在Web 开发中,图片预加载是一种常用的技术,如果直接给某个img 标签节点设置src 属性,
由于图片过大或者网络不佳,图片的位置往往有段时间会是一片空白。常见的做法是先用一张
loading 图片占位,然后用异步的方式加载图片,等图片加载好了再把它填充到img 节点里,这种
场景就很适合使用虚拟代理。

var myImage = (function(){
    var imgNode = document.createElement( 'img' );
    document.body.appendChild( imgNode );
    return {
        setSrc: function( src ){
            imgNode.src = src;
        }
  }
})();
myImage.setSrc( 'http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );

我们把网速调至5KB/s,然后通过MyImage.setSrc 给该img 节点设置src,可以看到,在图片被加载好之前,页面中有一段长长的空白时间。现在开始引入代理对象proxyImage,通过这个代理对象,在图片被真正加载好之前,页面中将出现一张占位的菊花图loading.gif, 来提示用户图片正在加载。代码如下:

var myImage = (function(){
    var imgNode = document.createElement( 'img' );
    document.body.appendChild( imgNode );
    return {
        setSrc: function( src ){
        imgNode.src = src;
        }
    }
    })();
var proxyImage = (function(){
    var img = new Image;
    img.onload = function(){
         myImage.setSrc( this.src );
    }
    return {
            setSrc: function( src ){
            myImage.setSrc( 'file:// /C:/Users/svenzeng/Desktop/loading.gif' );
            img.src = src;
        }
    }
})();

缓存代理用于ajax异步请求数据
我们在常常在项目中遇到分页的需求,同一页的数据理论上只需要去后台拉取一次,这些已经拉取到的数据在某个地方被缓存之后,下次再请求同一页的时候,便可以直接使用之前的数据。
这里写图片描述
一个网页中有4个tab标签,每切换一个就从后台抓取相对性的数据显示到content中。用缓存代理的话,每个tab只需要从后台抓取一次数据,减少请求。

//缓存代理去保存数据
var proxyAjaxData=(function(){
    var cache={};
    return function(obj){//传入参数
        if(obj in cache){
            return cache[obj];//保存在cache中
    }
        return cache[obj]=getData();//从后台抓取的数据
    }
})();

本文章参考:《Javascript设计模式与开发实践》—–AlloyTeam出品

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

IOS设计模式第一篇之MVC

设计模式的好处:我们可以写出容易理解,重用度很高的代码。降低代码的耦合度,符合软件工程的思想。 设计模式主要分为三类:创造型的:单例和抽象工厂。结构类型的: MVC  Decorator,...

笑谈设计模式(第一篇)

都说软件世界是现实世界的抽象,现实世界的事物都可以用软件来反应。在软件世界中,有一套解决通用问题的方法,高大上的讲法是:设计模式。 说起设计模式,懂得软件的人,都会肃然起敬,因为它在这个行业一直是...

Android Ap 开发 设计模式第一篇:迭代器模式

看到这个android设计模式,不知道文章质量如何,先转载过来,至少因为题目 转载地址:http://www.cnblogs.com/TerryBlog/archive/2011/07/05/209...

第一篇 设计模式之简单工厂模式

欢迎转载http://blog.csdn.net/Passi_zxj/article/details/52751969简介 简单工厂模式又叫静态工厂方法(Static Factory Method)模...

Android编程思想,面向对象程序设计第一篇——设计模式6个原则

做了几年的安卓,发现很多安卓从业者并不是计算机科班出身,很多都是转业或者在培训机构培训之后成为了一名安卓开发者。在接触了一些同行之后,发现比较多的初级开发者只对安卓API有一定的了解。但是对于整个项目...

设计模式连载:第一篇转职系统模式

待续

Android Ap 开发 设计模式第一篇:迭代器模式

Iterator Pattern迭代器模式 场景猜想   经常编写代码都会碰到遍历一个数组,使用for循环得到数组下标之后去做进一步操作。例如下文代码:    int[] array=ne...

设计模式第一篇 工厂模式(1) 简单工厂模式simple factory

工厂模式专门负责将拥有共同接口的类实例化。工厂模式可以动态的决定需要实例化哪个具体类,不必事先知道每次实例化哪个类! 工厂模式主要有三种形态: 1、简单工厂模式 simple factory : (又...

第一篇、创建型设计模式——简单工厂模式(静态工厂方法模式)

在具体学习设计模式之前,想要了解什么是设计模式,以及为什么要学习设计模式。 简单来说,设计模式就是一套被人们反复应用,形成了一套代码编写规范的经验以及结构总结。我们通过设计模式的学习,可以有意识地将业...

java设计模式第一篇 单例设计模式

aa
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)