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实现接口的三种经典方式的主要内容,如果未能解决你的问题,请参考以下文章

mybatis之接口方法多参数的三种实现方式

java 代理的三种实现方式

HTML中使用JavaScript的三种方式及优缺点

实现servlet的三种方式

使用JavaScript判断图片是否加载完成的三种实现方式

创建线程的三种方式的对比?