一、javascript接口描述
1、接口是面向对象javascript程序员的工具箱中最有用的工具之一,那么对于javascript没有定义接口的概念,我们通过模拟高级程序语言的方式来创建javascript中的接口。
2、接口的概念:提供一种以说明一个对象应该有哪些方法的手段。
二、通常建立接口的三种方式
1、注释描述接口
// 1 注释描述的方式
/**
* interface Composite {
* function add(obj){};
* function remove(obj){};
* function update(obj){};
* }
*/
//CompositeImpl implements Composite
var CompositeImpl = function () {
}
CompositeImpl.prototype.add = function () {
alert('add something');
}
CompositeImpl.prototype.remove = function () {
alert('remove something');
}
CompositeImpl.prototype.update = function () {
alert('update something');
}
var b1 = new CompositeImpl();
var b2 = new CompositeImpl();
alert(b1.add == b2.add);//true
b1.add();//add something
2、属性检测接口
// 2 属性检测的方式
/**
* interface Composite {
* function add(obj){};
* function remove(obj){};
* function update(obj){};
* }
* interface FormItem {
* function select(obj){};
*
* }
*/
//CompositeImpl implements Composite
var CompositeImpl = function () {
//显示的在类的内部 接受所实现的接口
// 一般来说是一个规范 在类的内部定义一个数组(名字要固定)
this.implementsInterfaces = ['Composite','FormItem'];
}
CompositeImpl.prototype.add = function () {
alert('add something');
}
CompositeImpl.prototype.remove = function () {
alert('remove something');
}
CompositeImpl.prototype.update = function () {
alert('update something');
}
CompositeImpl.prototype.select = function () {
alert('select something');
}
//检测CompositeImpl类的对象的
function checkCompositeImpl (instance) {
if(!isImplements(instance,'Composite','FormItem')) {
//isImplements 函数判断当前对象是否实现了所有的接口 封装好以便重用
throw new Error('Object does not implement a required instance!')
}
}
// 公用的具体检测方法(核心方法) 返回值类型 boolean
// 这个方法主要目的:判断,实例对象 有没有实现相关的接口
function isImplements (obj) {
//arguments 对象 获得函数的实际参数
for (var i = 1 , len = arguments.length; i < len; i++) {
var interfaceName = arguments[i],
interfaceFound = false;
for (var j = 0; j < obj.implementsInterfaces.length; j++) {
if(obj.implementsInterfaces[j] == interfaceName) {
interfaceFound = true;
break;
}
};
if(!interfaceFound) {
return false;
}
}
return true;
}
var b1 = new CompositeImpl();
checkCompositeImpl(b1);//此处检验是否实现接口函数 如果少实现一个接口会报一个错误
b1.add();//add something
这种方式的优点:,实现了检查接口是否完全被实现 缺点:这种属于文档的范畴,但接口的方法未检测,也不是面向对象的编程思想
3、鸭式辩型接口
// 3、鸭式辩型法实现接口(最完美的javascript实现接口的方式)
//1.接口类 Class Interface ==>实例化N多个接口
/**
* 接口类需要2个参数
* 参数1:接口的名字 (string)
*
* 参数2:接受方法名称的集合 (array)
*
*/
var Interface = function(name,methods) {
//判断接口的参数个数
if(arguments.length !== 2) {
throw new Error('arguments.length must be 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('arguments must be string!')
}
this.methods.push(methods[i]);
}
}
//实例化接口对象
var CompositeInterface = new Interface('CompositeInterface',['add','remove','update']);
var FormItemnterface = new Interface('FormItemnterface',['select'])
//2 准备工作:具体的实现类 CompositeImpl implements CompositeInterface,FormItemnterface
var CompositeImpl = function () {
}
CompositeImpl.prototype.add = function () {
alert('add something');
}
CompositeImpl.prototype.remove = function () {
alert('remove something');
}
CompositeImpl.prototype.update = function () {
alert('update something');
}
CompositeImpl.prototype.select = function () {
alert('select something');
}
Interface.ensureImplements = function (obj) {
//判断接口的参数个数<2的话,参数传递失败
if(arguments.length < 2) {
throw new Error('arguments.length must be >=2!')
}
//获得接口实例对象
for (var i = 1 , len = arguments.length; i < len; i++) {
var instanceInterface = arguments[i];
//判断参数是否是接口类的类型
if(instanceInterface.constructor !== Interface) {
throw new Error('arguments constructor must be Interface Class!')
}
//循环接口实例对象里面的每一个方法
for (var j = 0 , len = instanceInterface.methods.length; j < len; j++) {
var methodName = instanceInterface.methods[j];
//object[key] 就是方法
if(!obj[methodName] || typeof obj[methodName] !=='function') {
throw new Error('the methods is not found!')
}
};
}
}
var b1 = new CompositeImpl();
Interface.ensureImplements(b1,CompositeInterface,FormItemnterface);//此处检验是否实现接口函数 如果少实现一个接口会报一个错误
b1.add();//add something
这种方式是最完美的javascript实现接口的方式,接口里的方法都实现了,面向对象编程 代码也实现了统一 也解耦了。
三、接口的利弊
1、对于一些中小型程序来说 使用接口很显然是不明智的,对项目来说接口的好处并不明显,只是徒增其复杂度而已
2、对于接口的好处,那么显而易见,首先促进代码的重用,对于开发来讲,还可以告诉程序员哪些类都使用了什么方法,如果你事先知道接口,那么就减少了你在编码的时候对类与类之间冲突,实现解耦,对于测试和调试也会变得轻松,用于javascrit弱类型语言,类型不匹配经常出现,那么使用接口,这一点会变得容易一些。