JavaScript实现接口的三种经典方式
Posted 稀里糊涂林老冷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript实现接口的三种经典方式相关的知识,希望对你有一定的参考价值。
1 /* 2 接口:提供一种说明一个对象应该有哪些方法的手段 3 js中有三种方式实现接口: 4 1 注释描述接口 5 2 属性检测接口 6 3 鸭式辨型接口 7 */ 8 9 /* 10 1 注释描述接口: 不推荐 11 优点: 利用注解,给出参考 12 缺点:纯文档约束,是一个假接口, 13 程序不能检查实现接口对象是否实现所有接口方法 14 */ 15 16 /** 17 * interface Composite{ 18 * function a(); 19 * function b(); 20 * } 21 */ 22 // CompositeImpl implements Composite 23 var CompositeImpl = function(){ 24 //业务逻辑 25 }; 26 CompositeImpl.prototype.a = function(){ 27 //业务逻辑 28 }; 29 CompositeImpl.prototype.b = function(){ 30 //业务逻辑 31 }; 32 33 34 35 36 37 38 39 /* 40 2 属性检测接口: 41 优点:能够检测实现哪些接口 42 缺点:没有完全脱离文档, 43 不能检测是否实现每个接口里的所有方法 44 */ 45 /** 46 * interface Composite{ 47 * function a(); 48 * } 49 * 50 * interface FormItem(){ 51 * function b(); 52 * } 53 */ 54 // CompositeImpl implements Composite,FormItem 55 var interfacesImpl = function(){ 56 //在实现类内部用一个数组保存要实现的方法名 57 //通常这个属性名是团队中规定好的 58 this.implementsInterfaces = ["Composite","FormItem"]; 59 }; 60 CompositeImpl.prototype.a = function(){ 61 //业务逻辑 62 }; 63 CompositeImpl.prototype.b = function(){ 64 //业务逻辑 65 }; 66 67 //专门为这个实现对象写一个检测函数,传入实例对象,用于检查实力对象是否实现了所有接口 68 function checkImplements(obj){ 69 //调用检查方法 obj是否实现两个接口,如果没有都实现则抛出异常 70 if(!isImplements(obj,"Composite","FormItem")){ 71 throw new Error("接口没有全部实现!"); 72 } 73 //接收一个参数obj是要检查的对象 74 function isImplements(obj){ 75 //arguments对象能够获取实际传入函数的所有参数的数组 76 //传入的第0个参数是要检查的对象,所以从1开始检查 77 for(var i = 1; i < arguments.length ; i++){ 78 //接收接口中每个接口的名字 79 var interfaceName = arguments[i]; 80 //一个标记,是否实现这个接口,默认没有 81 var foundFlag = false; 82 //循环查询传入实例对象的实现接口数组 以检查是否全部实现 83 for(var j = 0 ;j <obj.implementsInterfaces.length;j++){ 84 //如果 实现了这个接口 就修改标记跳出循环 85 if(obj.implementsInterfaces[j]==interfaceName){ 86 foundFlag = true; 87 break; 88 } 89 } 90 //如果遍历实现接口数组之后没找到 就返回false 91 if(!foundFlag){ 92 return false; 93 } 94 } 95 //如果都找到了 返回true 96 return true; 97 } 98 } 99 100 //使用实力对象并检测 101 var o = new interfacesImpl(); 102 checkImplements(o); //不会抛出异常 因为正确实现了两个接口 103 //如果在写interfacesImpl内的implementsInterfaces列表的时候少写了,那么就会在检查函数中抛出异常 104 105 106 107 108 /* 109 3 鸭式辨型法:(目前开发中使用的方式) 110 实现思想: 111 112 */ 113 114 //1 接口类 Class Interface 115 /** 116 * 接口类需要的参数: 117 * 1 接口的名字 118 * 2 要实现方法名称的数组 119 */ 120 var Interface = function( name , methods ){ 121 //判断参数个数 122 if(arguments.length!=2){ 123 throw new Error("接口构造器参数必须是两个!"); 124 } 125 this.name = name; 126 this.methods = []; 127 for(var i = 0;i<methods.length;i++){ 128 if( typeof methods[i] !== "string" ){ 129 throw new Error("接口实现的函数名称必须是字符串!"); 130 } 131 this.methods.push(methods[i]); 132 } 133 134 }; 135 //2 准备工作: 136 // 2.1 实例化接口对象 传入接口名 和 要实现的方法数组 137 var CompositeInterface = new Interface("CompositeInterface",["add","remove"]); 138 var FormItemInterface = new Interface("FormItemInterface",["update","select"]); 139 140 // 2.2 实现接口的类 141 //CompositeImpl implementes CompositeInterface ,FormItemInterface 142 var CompositeImpl = function(){ 143 144 }; 145 // 2.3 实现接口的方法 146 CompositeImpl.prototype.add = function(obj){ 147 alert("add..."); 148 }; 149 CompositeImpl.prototype.remove = function(obj){ 150 alert("remove..."); 151 }; 152 CompositeImpl.prototype.select = function(obj){ 153 alert("select..."); 154 }; 155 //在这里少实现一个方法 下面检测是否全部实现了接口方法 156 // CompositeImpl.prototype.update = function(obj){ 157 // alert("update..."); 158 // }; 159 // 实例化 实现接口的对象 160 var c = new CompositeImpl(); 161 162 //3 检验接口里的方法是否全部实现 163 // 如果检验通过 继续执行;如果不通过抛出异常; 164 Interface.ensureImplements = function(obj){ 165 // 如果接收到参数小于2 说明 传参出错了,只传入一个参数,,没有传入实现的接口 166 if(arguments.length<2){ 167 throw new Error("接口检查方法的参数必须多余两个!"); 168 } 169 //获得要见测的接口实现对象之后的参数 各个接口 170 for(var i = 1,len = arguments.length;i<len;i++){ 171 var instanceInterface = arguments[i]; //获取当前这个接口 172 //判断接收到的是不是接口的对象 如果不是 抛出异常 173 if( instanceInterface.constructor !== Interface){ 174 throw new Error("接口检测函数必须传入接口对象!"); 175 } 176 //检查实例化接口的对象是不是实现了接口里的所有方法 177 // 当前接口对象里的每一个方法 178 for(var j = 0 ; j<instanceInterface.methods.length;j++){ 179 var methodName = instanceInterface.methods[j]; //接收到了字符串的方法名 180 //如果obj里面没有有methodName这个方法 或者有这个属性但是不是函数 就抛出异常 181 if(!obj[methodName] || typeof obj[methodName] !== "function"){ 182 throw new Error("接口方法"+ methodName +"没有实现!"); 183 } 184 } 185 } 186 187 188 }; 189 //传入要检查的类,和他要实现的所有接口对象 190 Interface.ensureImplements(c ,CompositeInterface ,FormItemInterface ); 191 c.add(); 192
以上是关于JavaScript实现接口的三种经典方式的主要内容,如果未能解决你的问题,请参考以下文章