• 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     
  • 相关阅读:
    解决duplicate symbols for architecture x86_64错误
    IOS-UITextField键盘不隐藏问题
    IOS-细节错误
    IOS开发-图片上传
    IOS-指定返回Modal的控制器presentViewController
    支付-支付宝集成
    真机测试-Please enter a different string错误解决
    Xcode插件安装 错选了Skip Bundle解决办法
    SQLServer 命令批量删除数据库中指定表(游标循环删除)
    SQL中使用update inner join和delete inner join
  • 原文地址:https://www.cnblogs.com/Lin-Yi/p/7455521.html
Copyright © 2020-2023  润新知