小议javascript设计模式
作者:oldfish 来源:alipay UED 发布时间:2009-10-09 13:31:00
最近重新温习了一次《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方法时会怎么样?建议新手,各类情况都模拟一下,加强理解吧!如果你确信已经完全理解接口设计,那就跟着我继续往下走。


猜你喜欢
- 在main.js里进行全局注册 Vue.prototype.funcName = function (){}在所有组件里可调用this.fu
- 本文较为详细的分析了Python解释执行的原理,对于深入理解Python可以起到一定的帮助作用。具体分析如下:首先,这里的解释执行是相对于编
- 昨天还和裕波沟通我没有准备ppt,想以另一种互动的方式来交流。后来想想,每个人都准备了,我不准备也不太好意思,呵呵。今天在webrebuil
- with/as使用open打开过文件的对with/as都已经非常熟悉,其实with/as是对try/finally的一种替代方案。当某个对象
- 前言Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架到目前为止,当我们的程序涉及到数据库相关操作时,我们一般
- Mac 安装 Python3.10 并且配置环境一、Python的安装访问官网:https://www.python.org/选择系统(Ma
- 1.pickle对象串行化pickle模块实现了一个算法可以将任意的Python对象转换为一系列字节。这个过程也被称为串行化对象。可以传输或
- 使用python进行websocket的客户端压力测试,这个代码是从github上 找到。然后简单修改了下。大神运用了进程池,以及线程池的内
- 1.代码准备没有语法错误的Python程序:#!/usr/bin/pythonimport numpy as npclass Network
- 废话不多说,直接上代码吧!#python中,while语句用于循环执行程序,即在某个条件下,循环执行某段程序,以处理需要重复处理的相同任务。
- 最近看到了两行 JavaScript 代码,很受启发。1. 封装 DOM 属性在 JavaScript 中,我们可以获取HTML元素的属性值
- 目录概述索引数据结构二叉树红黑树B-TreeB+TreeHash索引InnoDB 索引实现(聚集)索引文件和数据文件是分离的(非聚集)聚集索
- 本文实例讲述了Python3实现并发检验代理池地址的方法。分享给大家供大家参考,具体如下:#encoding=utf-8#author: w
- 这年头,信息和获得信息的渠道越来越多。随着信息量的增大,先有了分类,又有了导航,再有了搜索,后面的发展还不得而知。在此只是根据平日的所看所想
- 3. 迭代器3.1. 迭代器(Iterator)概述迭代器是访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素都
- 一、pyqt5的UI中嵌入matplotlib的方法1、导入模块导入模块比较简单,首先声明使用pyqt5,通过FigureCanvasQTA
- vue项目用webpack打包想要修改静态资源路径等,找到项目根目录下的config文件夹,打开该文件夹下的index.js文件,默认如下:
- python控制鼠标键盘其实很容易,我们在写程序的时候很多时候会用的到!python控制鼠标键盘步骤及代码1、安装类库pip install
- tf.keras.layers.Conv2D() 函数Conv2D (二维卷积层)这一层创建了一个卷积核,它与这一层的输入卷积以产生一个输出
- Python 数据库编程,ODBC方式实现通讯录,供大家参考,具体内容如下#-*-coding:utf-8-*-import pyodbci