接口:利 固化一部分代码 弊 丧失js的灵活性
在JavaScript中模仿接口
/* interface Composite{ function add(child); function remove(child); function getChild(index); } interface FormItem{ function save(); } */ var CompositeForm=function(id,method,action){ ... }; CompositeForm.prototype.add = function(child) { ... }; CompositeForm.prototype.remove = function(child) { ... }; CompositeForm.prototype.getChild = function(index) { ... }; 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."); } ... } 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;j++){ if (Object.implementsInterfaces[j]==interfaceName) { interfaceFound=true; break; }; } if (!interfaceFound) { return false; }; } return true; }
用鸭式辨型模仿接口
var Composite =new Interface('Composite',['add','remove','getChild']); var FormItem=new Interface('FormItem',['save']); var CompositeForm=function(id,method,action){ ... }; ... function addForm(formInstance){ ensureImplements(formInstance,Composite,FormItem); ... }
结合第一种和第三种
var Composite =new Interface('Composite',['add','remove','getChild']); var FormItem=new Interface('FormItem',['save']); var CompositeForm=function(id,method,action){ ... }; ... function addForm(formInstance){ Interface.ensureImplements(formInstance,Composite,FormItem); ... }
Interface类的定义
var Interface=function(name,method){ if(arguments.length!=2){ throw new Error("需要2个参数"); } this.name=name; this.method=[]; for(var i=0,len=methods.length;i<len;i++){ if(typeof methods[i]=='string'){ throw new Error("需要是一个字符串"); } this.methods.push(methods[i]); } }; Interface.ensureImplements=function(object){ if(arguments.length<2){ throw new Error("至少需要2个参数"); } for(var i=1,len=arguments.length;i<len;i++){ var interface=arguments[i]; if(interface.constructor!=Interface){ throw new Error("需要2个参数,并是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('方法未找到'); }; } } };