javascript常见的设计模式

转自:http://blog.csdn.net/yingyiledi/article/details/26725795


近日重读《javascript面型对象编程指南》这本书,最后一章介绍了常见的javascript设计模式的实现。主要讲解了四种设计模式:单例模式、工厂模式、装饰器模式和观察者模式。js作为动态语言,实现这四种模式的实例相对简单,当然既然称之为模式,那么吃透思想更重要,那么下面,由乐帝来实例讲解四种模式。

   1.单例模式

   顾名思义,对象构造出来的是实例,从字面上理解,单例即单实例,这意味一个类只能创建一个实例对象。当需要创建一种类型或者一个类的唯一对象时,可使用该模式。以下两个实例分别从全局变量和类属性两种角度构造单例。属于对象创建型模式。

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. function Logger(){  
  2.     if(typeof global_log==="undefined")  
  3.     {  
  4.         global_log=this;//没有在函数内定义global_log所以被看成全局变量,并且此时this为window为全局对象  
  5.         alert(this);//相当于初始化全局变量并且赋值为window,由于全局变量有唯一性,故可保证单例  
  6.     }  
  7.     return global_log;//但问题在于全局变量有可能被覆盖掉,造成实例流失  
  8. }  
  9. var a = new Logger();  
  10. var b = new Logger();  
  11. console.log(a===b);  

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //另外一种单例模式:构造器属性  
  2. function Logger(){//从面向对象的角度考虑,Logger是一个类  
  3.     if(typeof Logger.single_instance==="undefined"){  
  4.         Logger.single_instance=this;//Logger.single_instance则是类属性,这个也可以实现单例,类属性和私有属性不同,类属性是类实例公用的  
  5.         alert(this);  
  6.     }  
  7.     return Logger.single_instance;  
  8. }  
  9.   
  10. var a=new Logger()  
  11. var b=new Logger()  
  12. a===b;  

            2.工厂模式

   总的来说,工厂模式属于创建对象型模式,当有多个相似对象不知用哪种,可以考虑工厂模式。也属于创建型模式。

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //工厂模式  
  2. var MYAPP={};  
  3. MYAPP.dom={};  
  4. MYAPP.dom.Text=function(){  
  5.     this.insert=function(where){  
  6.         var txt=document.createTextNode(this.url);  
  7.         where.appendChild(txt);  
  8.     };  
  9. };//有三个相似的对象,三个对象中的方法一样,从而使用也一样  
  10.   
  11. MYAPP.dom.Link=function(){  
  12.     this.insert=function(where){  
  13.         var link=document.createElement('a');  
  14.         link.href=this.url;  
  15.         linlk.appendChild(document.createTextNode(this.url));  
  16.         where.appendChild(link);  
  17.     };  
  18. };  
  19. MYAPP.dom.Image=function(){  
  20.     this.insert=function(where){  
  21.         var im=document.createElement('img');  
  22.         im.src=this.url;  
  23.         where.appendChild(im);  
  24.     };  
  25. };  
  26.   
  27. /* var o=new MYAPP.dom.Image(); 
  28.  * o.url='www.baidu.com'; 
  29.  * o.insert(document.body); 
  30.  *  
  31.  * var o=new MYAPP.dom.Link(); 
  32.  * o.url='www.baidu.com'; 
  33.  * o.insert(document.body); 
  34.  *  
  35.  * var o=new MYAPP.dom.Text(); 
  36.  * o.url='www.baidu.com'; 
  37.  * o.insert(document.body); 
  38.  */  
  39. MYAPP.dom.factory=function(type){  
  40.     return new MYAPP.dom[type];  
  41. }//当构造器过多时,查找不那么一目了然,用工厂函数方法动态操作,省去了如上注释掉的操作或者if操作  
  42. var o=MYAPP.dom.factory("Image")//这种方法本质上用到了对象属性的一一对应关系  
  43. o.url='www.baidu.com';  
  44. o.insert(document.body);  

           3.装饰器模式

   此种模式是一种结构型模式,主要考虑如何拓展对象的功能。可以为一个基础对象创建若干装饰器对象以拓展其功能。由我们的程序自行选择不同装饰器,并使用它们。

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. var tree={};  
  2. tree.decorate=function(){  
  3.     alert("make sure the tree will not fall");  
  4. }  
  5. tree.getDecorator=function(deco){  
  6.     tree[deco].prototype=this;//返回新对象并且原tree作为新对象的原型对象  
  7.     return new tree[deco];  
  8. };  
  9. tree.RedBalls=function(){//tree的redball属性也是对象  
  10.     this.decorate=function(){  
  11.         this.RedBalls.prototype.decorate();//首先调用原型对象decorate方法  
  12.         alert("put on some red ball");  
  13.     }  
  14. };  
  15.   
  16. tree.BlueBalls=function(){  
  17.     this.decorate=function(){  
  18.         this.BlueBalls.prototype.decorate();//首先调用原型对象decorate方法  
  19.         alert("add blue ball");  
  20.     }  
  21. };  
  22.   
  23. tree.Angel=function(){  
  24.     this.decorate=function(){  
  25.         this.Angel.prototype.decorate();//首先调用原型对象decorate方法  
  26.         alert("an angel on the top");  
  27.     }  
  28. };//以上三个装饰器可按照需要选择  
  29. tree=tree.getDecorator("BlueBalls");//返回new tree["BlueBall"],并且保留对tree作为原型对象  
  30. tree=tree.getDecorator("RedBalls");//下两个类似  
  31. tree=tree.getDecorator("Angel");  
  32. tree.decorate();//当调用最后的decorate方法时,会分别上溯调用各自decorate方法中的原型对象方法调用  
  33. //装饰器模式的实现,关键在构造新对象时不断保留原对象作为原型对象,同时新对象的方法中,不断调用原型对象的同名方法  
  34. //总的来说就是保存原有对象功能的前提下,不断添加新的功能到原有对象  

         4.观察者模式

   此种模式属于行为型模式,主要处理对象之间的交互通信的问题。通常包含两类对象:发行商和订阅商。

   

[javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //观察者模式  
  2. //观察者模式分为推送和拉动两类,推送模式是由发行商负责将消息通知给各个订阅者,以下为推送模式实例  
  3. var observer={//观察这对象  
  4.     addSubscriber:function(callback){  
  5.         this.subscribers[this.subscribers.length]=callback;  
  6.     },//添加订阅者  
  7.     removeSubscriber:function(callback){  
  8.         for(var i=0;i<this.subscribers.length;i++){  
  9.             if(this.subscribers[i]===callback){  
  10.                 delete(this.subscribers[i]);  
  11.             }  
  12.         }  
  13.     },//移除订阅者  
  14.     publish:function(what){  
  15.         for(var i=0; i<this.subscribers.length;i++){  
  16.             if(typeof this.subscribers[i]==='function'){  
  17.                 this.subscribers[i](what);//广播信息后会传给每个订阅者  
  18.             }  
  19.         }  
  20.     },//接受并传递数据给订阅者  
  21.     make:function(o){  
  22.         for(var i in this){  
  23.             o[i]=this[i];  
  24.             o.subscribers=[];  
  25.         }  
  26.     }//将任意对象转化为发行商,并赋予以上三种方法,即获取添加、移除订阅者功能以及推送消息功能  
  27. };  
  28.   
  29. var blogger={  
  30.     writeBlogPost:function(){  
  31.         var content='Today is'+new Date();  
  32.         this.publish(content);//为成为发行商广播信息做准备的步骤  
  33.     }  
  34. };  
  35. observer.make(blogger);//构造blogger为发行商  
  36.   
  37. var jack={  
  38.     read:function (what){  
  39.         console.log('I just read that'+what);  
  40.     }  
  41. };//准备一个潜在订阅者  
  42. blogger.addSubscriber(jack.read);//添加订阅者,注意传送的是函数,这样在订阅者publish函数中就能调用订阅者的函数  
  43. blogger.writeBlogPost();//发布信息给订阅者  
  44. blogger.removeSubscriber(jack.read);//移除订阅者  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值