当前位置: 首页 > 科技观察

浅谈JavaScript中的接口实现

时间:2023-03-21 21:22:33 科技观察

1.什么是接口?接口是面向对象的JavaScript程序员工具箱中最有用的工具之一。设计模式中提出的可重用面向对象设计的原则之一是“面向接口编程而不是编程”,也就是我们所说的面向接口编程。可见这一概念的重要性。但问题在于,在JavaScript世界中,没有内置的方法来创建或实现接口,也没有办法确定一个对象是否实现了与另一个对象相同的一组方法,这使得使用起来很困难对象互换。幸运的是,JavaScript具有出色的灵活性,可以很容易地模拟传统的面向对象的接口并添加这些功能。接口提供了一种手段来描述一个对象应该有哪些方法,虽然它可以指明这些方法的含义,但是它并不包含具体的实现。使用此工具,可以根据对象提供的属性对对象进行分组。比如A和B和接口I,即使A对象和B对象差别很大,只要都实现了I接口,那么A和B在A.I(B)方法中是可以互换使用的,比如B.I(A)。接口也可用于利用不同类的共性。如果把原来需要特定类作为参数的函数改成需要特定接口作为参数的函数,那么所有实现了该接口的对象都可以作为参数传递给它,这样就互相没有关联了。对象也可以同样对待。二、接口的优缺点建立的接口是自描述的,可以促进代码的可重用性。接口可以提供一种信息,告诉外部类需要实现哪些方法。它还有助于稳定不同类之间的通信方式,减少在继承两个对象的过程中出现的问题。这也有助于调试。在像JavaScript这样的弱类型语言中,很难跟踪类型不匹配。在使用接口的时候,如果出现问题,会有更清晰的错误提示。当然,接口并非完全没有缺点。如果接口被广泛使用,其作为弱类型语言的灵活性将在一定程度上被削弱。另一方面,JavaScript并没有内置对接口的支持,只是模拟了传统的面向对象的接口。这会使本来就更灵活的JavaScript更难导航。此外,任何实现接口的方式都会影响性能,部分原因是额外的方法调用开销。使用接口的最大问题是,与其他强类型语言不同,如果不遵守接口约定,JavaScript将无法编译。它的灵活性可以有效避免上述问题。如果是在协同开发环境下,它的接口很可能没有任何错误就被破坏了,也就是不可控性。在面向对象的语言中,接口的使用方式大致相同。接口中包含的信息描述了类需要实现的方法以及这些方法的签名。类定义必须明确声明它们实现了这些接口,否则将无法编译。显然我们不能在JavaScript中做同样的事情,因为没有interface和implement关键字,也没有运行时检查接口是否遵循契约,但我们可以通过辅助方法和显式检查来模仿它的大部分功能。3.模仿JavaScript中的界面JavaScript中模仿界面的方式主要有三种:注解、属性检查和鸭式辩论。以上三种方式的有效结合,会产生类似界面的效果。注释是一种更直观的模拟接口的方式,将接口相关的关键字(如interface、implement等)与JavaScript代码一起放在注释中。这是最简单的方法,但效果最差。代码如下://模仿注释形式的描述界面/*interfaceComposite{functionadd(child);functionremove(child);functiongetName(index);}interfaceFormItem{functionsave();}*//模仿使用注释形式的接口关键字varCompositeForm=function(id,method,action){//implementsComposite,FormItem//dosomething}//这里模拟实现具体的接口方法implementCompositeinterfaceCompositeForm.prototype.Add=function(){//dosomething}CompositeForm.prototype.remove=function(){//dosomething}CompositeForm.prototype.getName=function(){//dosomething}//模拟实现具体接口方法这里,实现FormItem接口Composite.prototype.save=function(){//dosomething}这个方法其实不太好,因为这种模仿只停留在文档规范的范围内。开发者是否会严格遵守协议还有待考量,是否遵守接口完全取决于开发者的自觉性。此外,该方法不检查函数是否实际实现了我们约定的“接口”。但是,这种方法也有优点。不需要额外的类或函数就很容易实现,并且可以提高代码的可重用性,因为类实现的接口都被注释了。这种做法不会影响文件占用的空间,也不会影响执行速度,因为注释的代码在部署的时候很容易去掉。但由于它不提供错误消息,因此对测试和调试帮助不大。下面的方法会检查接口是否被实现,代码如下:implementsinterfaces=['Composite','FormItem'];//将接口显式放入implementsinterfaces}//检查接口是否实现functionimplements(Object){for(vari=0;i工厂模式:对象工厂创建的具体对象会根据具体情况而有所不同。使用接口可以保证创建的对象可以互换使用,也就是说对象工厂可以保证它生产的对象实现了需要的方法;<2>组合模式:不使用接口就不可能使用这种模式,其中心思想是可以将对象组与其组成对象一样对待。这是通过接口完成的。如果你不做鸭式辩论或类型检查,那么组合模式就失去了大部分意义;<3>装饰者模式:装饰者的工作方式是透明地为另一个对象提供包装。这是通过实现一个与其他对象的接口完全相同的接口来实现的。对于外界来说,装饰器和它包装的对象没有区别,所以使用Interface来确保创建的装饰器实现了需要的方法;<4>命令方式:代码中所有命令对象都是通过接口实现同一批方法(如run、ecxute、do等)创建的Class,无需执行这些命令对象,不需要知道这些对象是什么是,只要他们知道他们已经正确地实现了接口。这允许创建具有高度模块化和低耦合度的API。