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     
时间: 2024-10-18 19:52:08

JavaScript实现接口的三种经典方式的相关文章

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

有时需要获取图片的尺寸,这需要在图片加载完成以后才可以.有三种方式实现,下面一一介绍. 一.load事件 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>img - load event</title> </head> <body> <img id="img1" src="http:/

javascript中构造函数的三种方式

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script type="text/javascript"> // 创建函数的三种方式: // 1 函数声明 // 2 函数表达式 //

JavaScript定义数组的三种方式(new Array(),new Array(&#39;x&#39;,&#39;y&#39;),[&#39;x&#39;,&#39;y&#39;])

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

JavaScript声明全局变量的三种方式

JavaScript声明全局变量的三种方式 JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即为显式声明详细如下: var test = 5; //全局变量 function a() { var cc=3; //局部变量 alert(test); } function b(){alert(test);} 声明方式二: 没有使用var,直接

JavaScript新手学习笔记3——三种排序方式(冒泡排序、插入排序、快速排序)

每种编程语言学到数组的时候,都会讲到排序算法,当时学C语言的时候,卡在排序算法.今天来总结一下javascript中如何实现三种排序算法. 1.冒泡排序(默认升序排列哦) 原理: 冒泡排序的原理,顾名思义,就是小数往上冒,大数往下沉.从第一个数开始,如果比第二个数大就交换位置,然后跟第三个数字进行比较大小,交换位置等. 举例一下,有数组[2,4,3,5,1] 第一次循环:2<4  不交换:4>3 交换:4<5不交换:5>1交换,故结果是[2,3,4,1,5]; 第二次循环:2<

Hibernate的Api以及三种查询方式

Hibernate  Api |-- Configuration       配置管理类对象 config.configure();    加载主配置文件的方法(hibernate.cfg.xml) 默认加载src/hibernate.cfg.xml config.configure("cn/config/hibernate.cfg.xml");   加载指定路径下指定名称的主配置文件 config.buildSessionFactory();   创建session的工厂对象 |--

Servlet三种实现方式

Servlet三种实现方式:实现Servlet接口,继承GenericServlet ,继承HttpServlet. 1.实现Servlet接口: import javax.servlet.*; import java.io.*; public class Hello implements Servlet{ //执行条件:reload,关闭tomcat,关机 public void destroy() { // TODO Auto-generated method stub System.out

Spring IOC的三种注入方式

Spring IOC三种注入方式: 1.    接口注入 2.    getter,setter方式注入 3.    构造器注入 对象与对象之间的关系可以简单的理解为对象之间的依赖关系:A类需要B类的一个实例来进行某些操作,比如在A类的方法中需要调用B类的方法来完成功能,叫做A类依赖于B类.控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术,由容器控制程序之间的关系,而不是由代码直接控制. 1.接口注入 public class ClassA {  private InterfaceB

canvas入门-1三种填充方式、渐变、模式

1.定义canvas的尺寸的时候最好用html的方式定义,用width和height的方式,用css会导致画布按照css设定的方式进行缩放,cavas内部是一个2d的渲染环境 2.一个canvas对应一个2d的渲染环境,绘制图形的操作都是在2d渲染环境中进行的 <canvas id="canvas-1" style="border:solid 1px gray;" width = "400" height="400"&g