JavaScript设计模式学习一之接口

来源:互联网 发布:最简单的java代码 编辑:程序博客网 时间:2024/05/22 18:23

看完了《JavaScript王者归来》,在图书馆找了《JavaScript设计模式》来看,之前设计模式方面的书看过:《Head First 设计模式》、《设计模式之禅》,GOF的《Design Patterns: Elements of Reusable Object-Oriented Software》看了一部分。记得以前没这些基础的时候,看《JavaScript设计模式》简直是不知道作者在说什么。

言归正传:

准确的说,JavaScript没有类的概念,都是对象,JavaScript是基于面向对象的语言,但是《JavaScript设计模式》的作者们非要说JavaScript是面向对象的(也不知道是不是翻译的过程中问题)。用JavaScript来描述那些设计模式的时候,需要通过JavaScript的一些特性(比如说闭包、原型)来模拟Java、C++等面向对象语言的一些特性(比如说类、接口、继承、public、private)。


书中说了三种模拟Interface的方法

第一种:用注释描述接口

我觉得这个就是一种内部约定,直接说“我实现了XX接口”,在语言上我个人觉得一点约束力都没有,这真不应该拿出来说,有点滥竽充数的感觉。

第二种:用属性检查模仿接口

需要一个叫做implements()的函数进行检查

 function implements(object){for(var i=1;i<arguments.length;i++){var interfaceName = arguments[i];var interfaceFound = false;for(var j=0;j<object.implementsInterfaces.length;i++){if(object.implementsInterfaces[j] == interfaceName){ //implementsInterfaces保存了接口定义的方法的名称interfaceFound = true;break;}}if(!interfaceFound){return false; //接口没有找到}}return true; }


这是《JavaScript设计模式》书中的一部分代码,作者的描述是这样的:

这种方法有几个优点。它对类所实现的接口提供了文档说明。如果需要的接口不在一个类宣称支持的接口之列,你会看到错误消息。通过利用这些错误,你可以强迫其他程序员声明这些接口。这种方法的主要缺点在于它并未确保类真正实现了自称实现的接口。只知道它是否说自己实现了接口,在创建一个类声明它实现了一个接口,但后来在实现该接口方法所规定的方法时却漏掉其中的某一个,找一个错误很常见,此时所有的检查都能通过,但那个方法却并不存在,这将在代码中埋下一个隐患。


随即引出了第三中方法:用鸭式辨型模仿接口

原理:如果对象具有与接口定义的方法同名的所有方法,那么就可以认为它实现了这个接口。

首先需要一个接口类Interface

 var Interface = function(name ,methods){…… }
接受两个参数:接口名称,方法名


这个Interface类还有一个静态方法 ensureImplements()

 Interface.ensureImplements = function(object){……}

实际用法是这样的:

  var Composite = new Interface('Composite',['add','remover','getChild']); var FormItem = new Interface('FormItem',['save']);  var CompositeForm = function(id,method,action){……  }  function addForm(formInstance){ensureensureImplements(formIntance,Composite,FormItem);//This function will throw an error if a required method is not implemented…… }

最后作者采用第一种和第三种方法实现接口,代码如下:

 var Interface = function(name,methods){if(arguments.length!=2){throw new Error("Interface constructor called with"+arguments.length+"arguments,but expected exactly 2.");}this.name = name;this.methods=[];for(var i=0, len = methods.length;i<len;i++){if(type methods[i] !=='string'){throw new Error("Interface constructor expects method names to be passed in as a string");}this.methods.push(methods[i]);} };  Interface.ensureImplements = function(object){if(arguments.length<2){throw new Error("Function Interface.ensureImplements call with"+arguments.length+"arguments,but expected at least 2.");}for(var i=1,len = arguments.length;i<len;i++){var interface = arguments[i];if(interface.constructor !== Interface){throw new Error("Function Interface.ensureImplements expects arguments two and "+"above to be instance of Interface");}for(var j=0, methodslen = interface.methods.length;j<methodslen;j++){var method = interface.methods[j];if(!object[method] || typeof object[method]!=='function'){throw new Error("function Interface.ensureImplements:object"+"does not implements the"+interface.name+"interface.Method"+method+"was not found");}}}; 


JavaScript在我之前乃至现在的印象中,他就是应用在浏览器客户端的的一个脚本语言,主要的应用对象是浏览器,他需要这么大费周章的去模拟类似java的特性吗?有这个需求吗?我现在还没发现,以后可能能发现。

设计模式在我的理解就是四个字:解耦、复用。

可能是我现在需求还没那么高,,没办法理解设计模式在JavaScript里作用