深入理解javascript之设计模式

设计模式

设计模式是命名、抽象和识别对可重用的面向对象设计有用的的通用设计结构。设计模式确定类和他们的实体、他们的角色和协作、还有他们的责任分配。

每一个设计模式都聚焦于一个面向对象的设计难题或问题。它描述了在其它设计的约束下它能否使用,使用它后的后果和得失。因为我们必须最终实现我们的设计模式,所以每个设计模式都提供了例子,代码来对实现进行阐释.

虽然设计模式被描述为面向对象的设计,它们基于那些已经被主流面向对象语言实现过的解决方案…”。

种类

设计模式可以被分成几个不同的种类。在这个部分我们将分为三类:创建型设计模式、结构设计模式、行为设计模式。

创建型设计模式

创建型设计模式关注于对象创建的机制方法,通过该方法,对象以适应工作环境的方式被创建。基本的对象创建方法可能会给项目增加额外的复杂性,而这些模式的目的就是为了通过控制创建过程解决这个问题。

属于这一类的一些模式是:构造器模式(Constructor),工厂模式(Factory),抽象工厂模式(Abstract),原型模式(Prototype),单例模式(Singleton)以及建造者模式(Builder)。

结构设计模式

结构模式关注于对象组成和通常识别的方式实现不同对象之间的关系。该模式有助于在系统的某一部分发生改变的时候,整个系统结构不需要改变。该模式同样有助于对系统中某部分没有达到某一目的的部分进行重组。

在该分类下的模式有:装饰模式,外观模式,享元模式,适配器模式和代理模式。

行为设计模式

行为模式关注改善或精简在系统中不同对象间通信。

行为模式包括:迭代模式,中介者模式,观察者模式和访问者模式。

下面我们通过分开介绍各个常用的设计模式,来加深对设计模式的理解。

构造器模式

构造器是一个当新建对象的内存被分配后,用来初始化该对象的一个特殊函数。对象构造器是被用来创建特殊类型的对象的,首先它要准备使用的对象,其次在对象初次被创建时,通过接收参数,构造器要用来对成员的属性和方法进行赋值。

由于javascript不支持类的概念,所以必须通过构造器来使用new关键字初始化对象。一个基础的构造器代码如下:

function Car( model, year, miles ) {this.model = model; this.year = year; this.miles = miles;this.toString = function () {return this.model + " has done " + this.miles + " miles"; };} // 使用: // 我们可以示例化一个Carvar civic = new Car( "Honda Civic", 2009, 20000 );var mondeo = new Car( "Ford Mondeo", 2010, 5000 ); // 打开浏览器控制台查看这些对象toString()方法的输出值// output of the toString() method being called on// these objectsconsole.log( civic.toString() );console.log( mondeo.toString() );

但是这样的话,继承起来比较麻烦,而且每个Car构造函数创建的对象中,toString之类的函数都会被重新定义。所以还是要利用原型,来实现最佳的构造器:

function Car( model, year, miles ) {this.model = model; this.year = year; this.miles = miles; }// 注意这里我们使用Note here that we are using Object.prototype.newMethod 而不是// Object.prototype ,以避免我们重新定义原型对象Car.prototype.toString = function () { return this.model + " has done " + this.miles + " miles";}; // 使用: var civic = new Car( "Honda Civic", 2009, 20000 );var mondeo = new Car( "Ford Mondeo", 2010, 5000 ); console.log( civic.toString() );console.log( mondeo.toString() );工厂模式

一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型。说的简单点,就像饮水机,要咖啡还是牛奶取决于你按哪个按钮。

简单工厂模式在创建ajax对象的时候可以体现出来,可以通过jquery中的$.ajax方法来理解,也可以通过我自己写的一个ajax方法来理解,地址在:

ajax("test002.txt",{type:"GET",data:{name:"liuf",age:23},onsuccess:function(responseText,xhr){document.getElementById("input").value=responseText;},onfail:function(){//document.write("fail");}});

ajax实际上就是一个工厂方法,至于到底是用get方法还是post方法,都由后面的代码来决定。这就是前面所说的“一个工厂能提供一个创建对象的公共接口,我们可以在其中指定我们希望被创建的工厂对象的类型”。

单例模式

单例模式之所以这么叫,是因为它限制一个类只能有一个实例化对象。经典的实现方式是,创建一个类,这个类包含一个方法,这个方法在没有对象存在的情况下,将会创建一个新的实例对象。如果对象存在,这个方法只是返回这个对象的引用。但是javascript本来就是无类的,所以简单地来说,就是没有就创建,有就不创建直接用。

那么我们看看现实中的案例吧,点击一个按钮后出现一个遮罩层,这是一个常用的需求吧。代码如下:

var createMask = function(){return document,body.appendChild( document.createElement(div) ); }$( 'button' ).click( function(){var mask = createMask();mask.show(); })

这样写就会出现一个问题,就是每次调用createMask都会创建一个新的div,虽然可以在隐藏遮罩层时将其remove,但是这样还是会带来性能的损耗,那么可以做如下改进,就是在页面一开始就创建div,代码如下:

var mask = document.body.appendChild( document.createElement( ''div' ) ); $( ''button' ).click( function(){mask.show(); } )

这样确实可以保证页面只会创建一个遮罩层,但是也有一个问题,就是如果用户不需要用到这个div,岂不是白白创建了它。于是我们可以借助一个变量来判断是否已经创建过div,代码如下:

var mask; var createMask = function(){ if ( mask ) return mask; else{ mask = document,body.appendChild( document.createElement(div) ); return mask; } }人之相识,贵在相知;人之相知,贵在知心。

深入理解javascript之设计模式

相关文章:

你感兴趣的文章:

标签云: