第1章 Javascript接口

Javascript接口 概要 接口是面向对象程序设计中最有用的工具之一,在《设计模式》一书中也提出可重用面向对象的设计的第一原则就说到:面向接口而非实现编程。 接口之利:  接口具有自我描述性,促进代码的重用;  接口可以稳定不同类之间的通信方式;  接口可以方便测试和调试; 接口之弊:  Javascript是一种弱类型语言,使用了接口降低了Javascript的表现能力;  Javascript对接口没有内置的支持,模仿接口的实现会加大Javascript的学习难度;  Javascript模仿接口的实现加大了资源的开销;  Javascript模仿的接口,无法强制其他程序员遵守你定义的接口; Javascript接口的实现 用注释的方法描述接口 这种方法并不好,它没有确保类正确实现了接口中的方法,只是一种规范,一点约束力也没有。 /* interface Composite { function add(child); function remove(child); function getChild(index); } interface FormItem { function save(); } */ var CompositeForm = function(id, method, action) { // implements Composite, FormItem //... }; // Implement the Composite interface. CompositeForm.prototype.add = function(child) { //... }; CompositeForm.prototype.remove = function(child) { //... }; CompositeForm.prototype.getChild = function(index) { //... }; // Implement the FormItem interface. CompositeForm.prototype.save = function() { //... }; 用属性检查模仿接口 这种方法,所有类都声明了自己实现哪些接口,但接口本省还只是注释。 /* interface Composite { function add(child); function remove(child); function getChild(index); } interface FormItem { function save(); } */ var CompositeForm = function(id, method, action) { this.implementsInterfaces = ['Composite', 'FormItem']; //... }; function addForm(formInstance) { if(!implements(formInstance, 'Composite', 'FormItem')) { throw new Error("Object does not implement a required interface."); } //... } // The implements function, which checks to see if an object declares that it // implements the required interfaces. function implements(object) { for(var i = 1; i < arguments.length; i++) { // Looping through all arguments // after the first one. var interfaceName = arguments[i]; var interfaceFound = false; for(var j = 0; j < object.implementsInterfaces.length; j++) { if(object.implementsInterfaces[j] == interfaceName) { interfaceFound = true; break; } } if(!interfaceFound) { return false; // An interface was not found. } } return true; // All interfaces were found. } 用鸭式辨型模仿接口 类是否声明自己支持哪些接口并不重要,只要它具有这些接口的方法就认为它实现了这些接口。(鸭式辨型理论) 这种方法借助于一个辅助类(Interface)和一个辅助函数(ensureImplements)来实现。但类并不声明自己实现了哪些类,降低了可重用性;同时也缺乏了自我描述性。所以最好的做法是将其和第一种方法结合起来。 // Interfaces. var Composite = new Interface('Composite', ['add', 'remove', 'getChild']); var FormItem = new Interface('FormItem', ['save']); // CompositeForm class var CompositeForm = function(id, method, action) { // implements Composite, FormItem ... }; ... function addForm(formInstance) { Interface.ensureImplements(formInstance, Composite, FormItem); // This function will throw an error if a required method is not implemented, // halting execution of the function. // All code beneath this line will be executed only if the checks pass. ... } // Constructor. 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(typeof methods[i] !== 'string') { throw new Error("Interface constructor expects method names to be " + "passed in as a string."); } this.methods.push(methods[i]); } }; // Static class method. Interface.ensureImplements = function(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++) { var interface = arguments[i]; if(interface.constructor !== Interface) { throw new Error("Function Interface.ensureImplements expects arguments " + "two and above to be instances 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 implement the " + interface.name + " interface. Method " + method + " was not found."); } } } }; 灵活性是Javascript最强大的特色之一,强制执行不必要的严格类型检查会损害这种灵活性,谨慎的使用接口类有助于创建健壮的类和更稳定的代码。
posted @ 2012-07-18 04:10  waynecn  阅读(93)  评论(0)    收藏  举报