1. 程式人生 > >JavaScript實現接口的三種經典方式

JavaScript實現接口的三種經典方式

pda osi 註釋 posit 檢查 form 兩個 const simple

  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實現接口的三種經典方式