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