搜索:
首页 >> JavaScript >> Js高级编程 >> 小议javascript设计模式

小议javascript设计模式

2009-10-9 作者:oldfish 来源:alipay UED 投递文章

最近重新温习了一次《javascript设计模式》,确实是一本好书,每次看都有不同的领悟,每次领悟到的都受益匪浅,无怪古圣人都说学无止镜了,仅以“加油,好吗?”共勉!

记得早前就说过要和大家分享“javascript设计模式”,迟迟没写不是因为我懒,最近确实太忙,忙工作,忙旅游(啊哦?),好不容易这几天空闲了,接下来是兑现之前空口白话的时间了。

在讨论设计模式之前,请确认您已经有一定的脚本编程基础,如果不甚了解,建议可以先查阅本人很久之前写的这篇《浅谈javascript面向对象编程》

讲到设计模式,不得不先重点着墨于“接口设计”,因为接口设计在设计模式中的意义太大了,大于模式本身。直观起见,先介绍一下接口定义的形式:

var interface = new Interface("interface",[["getName",1],["getAge",1]]);

可以看出接口函数必须包含两个参数,接口方法定义在一个二维数组中。上例中定义了两个接口方法:getName,getAge,这两个方法都带一个参数,下面我们详细看一下Interface函数的实现代码,从而加深大家对接口的理解。

function Interface(name,methods){ 

    if(arguments.length !=2){ 
      console.log("参数必须为二个"); 
    } 
    this.name = name; 
    this.methods = []; 
    if(methods.length<1){ 
     console.log("第二个参数不能为空数组"); 
    } 
    for(var i=0;len=methods.length,i<len;i++){ 
      if(typeof methods[i][0] !== 'string'){ 
          console.log("第一个参数数据类型必须为字符串"); 
      } 
      if(methods[i][1] && typeof methods[i][1] !== 'number'){ 
         console.log("第二个参数数据类型必须为整数型"); 
      } 
      if(methods[i].length == 1){ 
          methods[i][1] = 0; 
      } 
      this.methods.push(methods[i]); 
    } 
  }

从代码中不难看出,接口函数的定义规则:[1]Interface函数只能包含两个参数,第一个参数为接口名称,第二个参数是一个二维数组[2]第二个参数不允许为空数组[3]methods参数中的第一个参数必须为字符串类型,用以定义方法名,第二个参数必须为整数类型,用以定义方法的参数个数[4]当methods中方法的参数个数为0时,可以省略不写。

接下来要建一个类,让该类继承前面定义的interface接口,那该怎么做呢,别急,我们需要新增一个方法,见如下代码:

var ioldfish = function(name,age){ 

    this.name = name; 
    this.age = age; 
    Interface.regImplement(this,interface); 
  } 
  ioldfish.prototype.getName = function(){ 
      alert(this.name); 
  }; 
  ioldfish.prototype.getAge = function(){ 
      alert(this.age);  
  }; 
  
  var fishwl = new ioldfish("老鱼",27); 
  fishwl.getName();

Interface.regImplement就是我们要新增的方法,作用就是让ioldfish类按照接口interface的规范编码,否则将会在firebug的控制台抛出异常。

看看这个方法的具体实现代码:

Interface.regImplement = function(object){ 

      if(arguments.length<2){ 
        console.log("接口继承参数不能少于二个"); 
      } 
      for(var i=1;len = arguments.length,i<len;i++){ 
          var interface = arguments[i]; 
          if(interface.constructor !== Interface){ 
            console.log("第三个参数开始必须为接口实例"); 
          } 
          for(var j=0;len=interface.methods.length,j<len;j++){ 
              var method = interface.methods[j][0]; 
             if(!object[method] || typeof object[method] !=="function" || object[method].getParameters().length !== interface.methods[j][1]){ 
                console.log(""+method+"方法接口不匹配"); 
              } 
          } 
      } 
  }

解读这段代码,你很容易发现:[1]Interface.regImplement继承接口函数的参数至少要有两个,如果有第三个参数,那么该参数必须是Interface接口的实例[2]我们去遍历interface接口中的方法,再与新增类中的方法一一匹配,如果发现继承了该接口规范的类缺少某方法,就会抛出错误提示。[3]接口对于参数个数也进行了匹配,如果接口方法中的参数个数与新增类中方法的个数不匹配也会抛出错误提示。

为了匹配方法中参数个数,这里用到一个getParameters()方法,我们基于Function做个扩展,代码实现如下:

Function.prototype.getParameters = function(){ 

    var str = this.toString(); 
    var paramStr = str.slice(str.indexOf("(")+1,str.indexOf(")")).replace(/\s*/g,''); 
    try{ 
        return (paramStr.length ==0 ? [] : paramStr.split(",")); 
    } 
    catch(err){ 
        console.log("非法函数"); 
    } 
  }

接下来,你可以把所讲的Interface函数,Interface.regImplement函数,还有Function.prototype.getParameters函数整合到一个interface.js的文件中,调试一下新建的这个ioldfish类。看看当类中缺少getAge方法时会怎么样?建议新手,各类情况都模拟一下,加强理解吧!如果你确信已经完全理解接口设计,那就跟着我继续往下走。

1   2  3  4  5  6  7 下一页 尾 页
相关文章
手机版 Js高级编程 Asp之家 Aspxhome.com
闽ICP备06017341号