您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 冶金工业 > 常用的javascript设计模式
常用的javascript设计模式设计模式太多了,貌似有23种,其实我们在平时的工作中没有必要特意去用什么样的设计模式,或者你在不经意间就已经用了设计模式当中的一种。本文旨在总结平时相对来说用的比较多的设计模式。回到顶部什么是设计模式百度百科:设计模式(Designpattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。实际情况:设计模式绝对不是纸上谈兵的知识,光看书就以为自己懂了,那只是井底之蛙之见,设计模式绝对是从实践中来到实践中去的!如果编码经验很少,也不太可能能理解好设计模式,但凡软件设计能力强的人编码功底都是相当扎实的。如果没有能深刻理解面向对象,也不太可能理解好设计模式,刚刚毕业或者才工作一两年就说自己面向对象能力强的人,基本上就是夸夸其谈的人。很明显,我就是属于那种夸夸其谈的人,哈哈,不过希望对本文的总结,让自己更加了解这些设计模式,理解的更加透彻。回到顶部单体模式:概念:单体是一个用来划分命名空间并将一批相关的属性和方法组织在一起的对象,如果他可以被实例化,那么他只能被实例化一次。特点:可以来划分命名空间,从而清除全局变量所带来的危险。利用分支技术来来封装浏览器之间的差异。可以把代码组织的更为一体,便于阅读和维护。代码实现:/*BasicSingleton*/varSingleton={attribute:true,method1:function(){},method2:function(){}};应用场景:单体模式在我们平时的应用中用的比较多的,相当于把我们的代码封装在一个起来,只是暴露一个入口,从而避免全部变量的污染。回到顶部工厂模式:概念:工厂模式的定义:提供创建对象的接口,意思就是根据领导(调用者)的指示(参数),生产相应的产品(对象)。创建一个对象常常需要复杂的过程,所以不适合在一个复杂的对象中。创建对象可能会导致大量的重复代码,也可能提供不了足够级别的抽象。工厂就是把成员对象的创建工作转交给一个外部对象,好处在于消除对象之间的耦合(也就是相互影响)分类:简单工厂模式:使用一个类,通常为单体,来生成实例。复杂工厂模式定义是:将其成员对象的实列化推到子类中,子类可以重写父类接口方法以便创建的时候指定自己的对象类型。父类只对创建过程中的一般性问题进行处理,这些处理会被子类继承,子类之间是相互独立的,具体的业务逻辑会放在子类中进行编写。代码实现:简单工厂模式:varXMLHttpFactory=function(){};//这是一个简单工厂模式XMLHttpFactory.createXMLHttp=function(){varXMLHttp=null;if(window.XMLHttpRequest){XMLHttp=newXMLHttpRequest()}elseif(window.ActiveXObject){XMLHttp=newActiveXObject(Microsoft.XMLHTTP)}returnXMLHttp;}//XMLHttpFactory.createXMLHttp()这个方法根据当前环境的具体情况返回一个XHR对象。varAjaxHander=function(){varXMLHttp=XMLHttpFactory.createXMLHttp();...}复杂工厂模式:流程==》先设计一个抽象类,这个类不能被实例化,只能用来派生子类,最后通过对子类的扩展实现工厂方法varXMLHttpFactory=function(){};//这是一个抽象工厂模式XMLHttpFactory.prototype={//如果真的要调用这个方法会抛出一个错误,它不能被实例化,只能用来派生子类createFactory:function(){thrownewError('Thisisanabstractclass');}}varXHRHandler=function(){};//定义一个子类//子类继承父类原型方法extend(XHRHandler,XMLHttpFactory);XHRHandler.prototype=newXMLHttpFactory();//把超类原型引用传递给子类,实现继承XHRHandler.prototype.constructor=XHRHandler;//重置子类原型的构造器为子类自身//重新定义createFactory方法XHRHandler.prototype.createFactory=function(){varXMLHttp=null;if(window.XMLHttpRequest){XMLHttp=newXMLHttpRequest();}elseif(window.ActiveXObject){XMLHttp=newActiveXObject(Microsoft.XMLHTTP)}returnXMLHttp;}应用场景:以下几种情景下工厂模式特别有用:(1)对象的构建十分复杂(2)需要依赖具体环境创建不同实例(3)处理大量具有相同属性的小对象优点:可以实现一些相同的方法,这些相同的方法我们可以放在父类中编写代码,那么需要实现具体的业务逻辑,那么可以放在子类中重写该父类的方法,去实现自己的业务逻辑;也就是说有两点:1、弱化对象间的耦合,防止代码的重复。在一个方法中进行类的实例化,可以消除重复性的代码。2、重复性的代码可以放在父类去编写,子类继承于父类的所有成员属性和方法,子类只专注于实现自己的业务逻辑。缺点:当工厂增加到一定程度的时候,提升了代码的复杂度,可读性下降。而且没有解决对象的识别问题,即怎么知道一个对象的类型。回到顶部单例模式概念:单例模式定义了一个对象的创建过程,此对象只有一个单独的实例,并提供一个访问它的全局访问点。也可以说单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。代码实现:单例的实现有很多种,下面只介绍其中的一种,使用闭包方式来实现单例,代码如下:varsingle=(function(){varunique;functiongetInstance(){//如果该实例存在,则直接返回,否则就对其实例化if(unique===undefined){unique=newConstruct();}returnunique;}functionConstruct(){//...生成单例的构造函数的代码}return{getInstance:getInstance}})();上面的代码中,unique便是返回对象的引用,而getInstance便是静态方法获得实例。Construct便是创建实例的构造函数。可以通过single.getInstance()来获取到单例,并且每次调用均获取到同一个单例。这就是单例模式所实现的效果。使用场景:单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如全局缓存、浏览器的window对象。在js开发中,单例模式的用途同样非常广泛。试想一下,当我们单击登录按钮的时候,页面中会出现一个登录框,而这个浮窗是唯一的,无论单击多少次登录按钮,这个浮窗只会被创建一次。因此这个登录浮窗就适合用单例模式。总结一下它的使用场景:1、可以用它来划分命名空间2、借助单例模式,可以把代码组织的更为一致,方便阅读与维护回到顶部观察者模式(发布订阅模式)概念:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新,也被称为是发布订阅模式。它需要一种高级的抽象策略,以便订阅者能够彼此独立地发生改变,而发行方能够接受任何有消费意向的订阅者。应用场景:这个模式要先说应用场景,比较好理解。打一个离我们比较近的一个场景,博客园里面有一个订阅的按钮(貌似有bug),比如小A,小B,小C都订阅了我的博客,当我的博客一有更新时,就会统一发布邮件给他们这三个人,就会通知这些订阅者发布订阅模式的流程如下:1.确定谁是发布者(比如我的博客)。2.然后给发布者添加一个缓存列表,用于存放回调函数来通知订阅者。3.发布消息,发布者需要遍历这个缓存列表,依次触发里面存放的订阅者回调函数。4、退订(比如不想再接收到这些订阅的信息了,就可以取消掉)代码如下:varpubsub={};//定义发布者(function(q){varlist=[],//回调函数存放的数组,也就是记录有多少人订阅了我们东西subUid=-1;//发布消息,遍历订阅者q.publish=function(type,content){//type为文章类型,content为文章内容//如果没有人订阅,直接返回if(!list[type]){returnfalse;}setTimeout(function(){varsubscribers=list[type],len=subscribers?subscribers.length:0;while(len--){//将内容注入到订阅者那里subscribers[len].func(type,content);}},0);returntrue;};//订阅方法,由订阅者来执行q.subscribe=function(type,func){//如果之前没有订阅过if(!list[type]){list[type]=[];}//token相当于订阅者的id,这样的话如果退订,我们就可以针对它来知道是谁退订了。vartoken=(++subUid).toString();//每订阅一个,就把它存入到我们的数组中去list[type].push({token:token,func:func});returntoken;};//退订方法q.unsubscribe=function(token){for(varminlist){if(list[m]){for(vari=0,j=list[m].length;ij;i++){if(list[m][i].token===token){list[m].splice(i,1);returntoken;}}}}returnfalse;};}(pubsub));//将订阅赋值给一个变量,以便退订vargirlA=pubsub.subscribe('js类的文章',function(type,content){console.log('girlA订阅的'+type+:内容内容为:+content);});vargirlB=pubsub.subscribe('js类的文章',function(type,content){console.log('girlB订阅的'+type+:内容内容为:+content);});vargirlC=pubsub.subscribe('js类的文章',function(type,content){console.log('girlC订阅的'+type+:内容内容为:+content);});//发布通知pubsub.publish('js类的文章','关于js的内容');//输出://girlC订阅的js类的文章:内容内容为:关于js的内容//test3.html:78girlB订阅的js类的文章:内容内容为:关于js的内容//test3.html:75girlA订阅的js类的文章:内容内容为:关于js的内容//girlA退订了关于js类的文章setTimeout(function(){pubsub.unsubscribe(girlA);},0);//再发布一次,验证一下是否还能够输出信息pubsub.publish('js类的文章',关于js的第二篇文章);//输出:/
本文标题:常用的javascript设计模式
链接地址:https://www.777doc.com/doc-2452106 .html