关于JavaScript Interface 接口的实现探索

前几天花了些时间看了js大师Ross和Dustin写的js设计模式,的确是本好书啊,里面的东西讲的非常深入,对于js模拟java编程的模式有很大启发,对于对象的解耦也讲的非常细致,有时间这本书要细细的读一下,下面就书中关于JavaScript Interface方面的阐述下自己的看法。

首先JavaScript是弱类型语言,所以类型匹配问题很难追踪,同时,Js并没有像其他语言一样,提供内置的创建或实现接口的方法。这样,在我们进行对象转化的时候是很困难的。

不过,我们还是可以使用程序来模拟JavaScript Interface接口的实现。一般来说,模拟Interface的实现有如下三种方法:

注释法——将接口的定义写在注释中,大家能否小心注意,以实现接口的所有方法全凭自觉
属性检查法——自己说明我实现了哪些接口,一会儿你检查的时候记得检查我说我实现的接口里面,是否把我真正想要实现的接口全部实现了(这么别扭呢),总之就是自欺欺人
鸭式辨型法——像鸭子一样,嘎嘎叫的那么就是鸭子。具有鸭子特性的东西,我们就可以称之为鸭子。能直立行走,会使用工具的除了机器人,都是人。嗯~~
按照书中介绍的,我们也一样彩注释法与鸭式辨型相结合的方法,来模拟Js的接口实现。

// Constructor
/*
* @param name String 接口的名字
* @param methods Array 接口里面定义的方法
*/
var Interface = function(name, methods){
//如果购造函数的参数不等于2个,那么抛出异常
if (arguments.length != 2) {
throw new Error("Interface constructor called with " + arguments.length +
"arguments,but expected exactyl 2.")
}

this.name = name;
this.methods = [];
//方法数组,保证传进来的methods数组中,每一个元素都是字符串类型
for (var i = 0, len = methods.length; i < len; i++) {
if (typeof methods[i] !== "string") {
throw new Error("Interface constructor expects methods names to bo " +
"passed in asastring.");
}
this.methods.push(methods[i]);
}
}

//Static class methods
Interface.ensureImplements = function(object){
//如果参数少于2个,抛出异常,object是待判断实现接口的对象
if (arguments.length < 2) {
throw new Error("Function Interface.ensureImplements called with " + arguments.length +
"arguments,but expected at least 2.");
}
for (var i = 1, len = arguments.length; i < len; i++) {
//inter_face为接口,一定要实现Interface类
//书中使用interface,因是JavaScript中保留字,所以暂替换为inter_face
var inter_face = arguments[i];
if (inter_face.constructor !== Interface) {
throw new Error("Function Interface.ensureImplementsexpects arguments " +
"two and above to be instances of Interface.");
}
for (var j = 0, methodsLen = inter_face.methods.length; j < methodsLen; j++) {
//对象中是否含有接口中定义的方法
var method = inter_face.methods[j];
if (!object[method] || typeof object[method] !== 'function') {
throw new Error("Function Interface.ensureImplements: object " +
"does not implements the " +
inter_face.name +
"interface.Method " +
method +
"was not found.");
}
}
}
}


然后要使用接口则如下:

//定义接口Composite,实现add,remove,getChild三种方法
var Composite = new Interface('Composite',['add','remove','getChild']);

//定义接口FormItem,实现save方法
var FormItem = new Interface('FormItem',['save']);

//判断对象是否实现了上述两个接口
var object = new Class();
Interface.ensureImplements(object,Composite,FormItem);


其实这种模仿java的接口的实质是“检测”,就是说事实上上面的js代码不是模仿接口的实现机制,而是模仿java中检测一个class是否实现了这个interface中所有的抽象函数的抛错误的机制,这里在定义一个接口时,并没有像java中那样声明一个抽象函数,因为java是强类型的语言的,声明的抽象函数中必须要声明其函数的返回值类型,而js是弱类型的语言,直接用function声明就行了,既然不用声明返回值的类型,那js的接口内的函数实质是一个函数名称,所以在定义这个接口时,只要将函数名的数组传入构造函数即可,而Interface.ensureImplements(object,Composite,FormItem)则是检测接口中的函数是否都已重写,所以说这种模仿java的接口的实质是“检测”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值