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     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM