javascript语言不像java、 c#、 c++等面向对象语言那样有完备的接口支持,在javascript中,接口的实现有三种方式,分别为注释描述、属性检查、鸭式变形。注释描述实现起来最为简单,但是,接口约定的遵守纯靠自觉,而且也没有很好的度量措施,说到底,它主要还是属于程序文档范畴。其实,类是否申明自己支持哪些接口并不重要,只要它具有这些接口中的方法就行了。鸭式变形(这个名称来自James Whitcomb Riley的名言:"像鸭子一样嘎嘎叫的就是鸭子")正式基于这种认识。
下面来谈谈javascript中接口的具体实现策略。(基于鸭式变形,用的也是最多的哦~~)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 |
<em id= "__mceDel" > * 接口类构造函数,接受2个以上的参数,其中第一个参数为接口名,后面的参数可以为字符串数组,也可以为字符串 * @param {Object} name * 接口名 * @param {Object} methods * 接口包含的方法集合,参数可以为数组,也可以传入任意多的字符串形式的方法名 */ var
Interface = function (name, methods){ if (arguments.length < 2){ //若参数个数不为2,则抛出错误 throw
new Error( "Interface constructor called with"
+ arguments.length + "arguments, but expected at least 2" ); } this .name = name; this .methods = []; for ( var
i = 1, len = arguments.length; i < len; ++i){ if (arguments[i] instanceof
Array){ //若参数为数组,则遍历该参数 for ( var
j = arguments[i].length - 1; j > -1; --j){ if ( typeof
arguments[i][j] !== ‘string‘
){ //保证传入的方法名为字符串,否则抛出错误 throw
new Error( ‘Interface constructor expects method names to be passed in as a string‘ ); } this .methods.push(arguments[i][j]); //保存方法名 } } else
if ( typeof
arguments[i] === ‘string‘ ){ //参数为字符串,直接保存 this .methods.push(arguments[i]); } else
{ //否则抛出错误 throw
new Error( ‘Interface constructor expects method names to be passed in as a string‘ ); } } }; /* * 接口实现检验函数,第一个参数为要检查的对象,后面的任意参数为实现的接口对象,也可以为接口对象数组 * @param {Object} object */ Interface.ensureImplents = function (object){ if (arguments.length < 2){ throw
new Error( "Interface constructor called with"
+ arguments.length + "arguments, but expected at least 2" ); } var
_checkMethods = function (inface){ //内部函数,用于检验对象是否实现了ifs对象中的方法 var
methods = inface.methods, i = methods.length - 1; for ( ; i > -1; --i){ var
method = methods[i]; //若对象不存在该属性,或者该属性不是方法,那么抛出错误 if ( typeof
object[method] === ‘undefined‘
|| typeof
object[method] !== ‘function‘ ){ throw
new Error( "Function Interface.ensureImplents: object does not implent the "
+ inface.name + "interface. Method "
+ method + " was not found."
); } } }; for
( var
i = arguments.length - 1; i > 0; --i) { if (arguments[i] instanceof
Array){ for ( var
j = arguments[i].length - 1; j > -1; --j){ if (!arguments[i][j] instanceof
Interface){ throw
new Error( ‘Function Interface.ensureImplents expects arguments two and above to be‘
+ ‘instances of Interface‘ ); } _checkMethods(arguments[i][j]); //检验接口实现 } } else
if (arguments[i] instanceof
Interface){ _checkMethods(arguments[i]); //检验接口实现 } else
{ throw
new Error( ‘Function Interface.ensureImplents expects arguments two and above to be‘
+ ‘instances of Interface‘ ); } } };</em> |
1 |
编写出上述代码挺简单,主要思路就是检测传入参数的类型和名称。看看某个具体实现类有没有实现所定义的接口中的那些 function 。。<br> 下面给出一个调用接口的例子吧~ |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 |
//2个接口实例 var
ITest = new
Interface( ‘ITest‘ , ‘test0‘ , [ ‘test1‘ , ‘test2‘ ], ‘test3‘ ); var
ISay = new
Interface( ‘ISay‘ , ‘say0‘ , ‘say1‘ ); //未继承的任何对象,仅是实现了ITest接口 var
implentTest = { test0: function (){ alert( ‘test0‘ ); }, test1: function (){ alert( ‘test1‘ ); }, test2: function (){ alert( ‘test2‘ ); }, test3: function (){ alert( ‘test3‘ ); } } var
implentSay = { say1: function (){ alert( ‘say1‘ ); }, say0: function (){ alert( ‘say0‘ ); } }; function
TestAndSay (){ this .say0 = function (){ alert( ‘test0 and say0‘ ); }; this .say1 = function (){ alert( ‘tes1t and say1‘ ); }; } TestAndSay.prototype = implentTest; //一个简单的继承 var
implentTestAndSay = new
TestAndSay(); //实例化 function
test(ITestInstance){ Interface.ensureImplents(ITestInstance, ITest); ITestInstance.test0(); ITestInstance.test1(); ITestInstance.test2(); } function
say(ISayInstance){ Interface.ensureImplents(ISayInstance, ISay); ISayInstance.say0(); ISayInstance.say1(); } function
sayAndtest(inst){ Interface.ensureImplents(inst, ISay, ITest); inst.test0(); inst.say0(); inst.say1(); } test(implentTest); //弹出3个对话框:test0 test1 test2 //test(implentSay);将会抛出错误 //say(implentTest); 将会抛出错误 say(implentSay); //弹出2个对话框 say0 say1 sayAndtest(implentTestAndSay); //弹出3个对话框: test0; test0 and say0; test1 and say1 |
哈哈,有了接口的定义及实现后,你就可以在设计模式中充分发挥你的才能了,让设计模式为我们服务吧!
javascript设计模式开篇:Javascript 接口的实现,布布扣,bubuko.com
javascript设计模式开篇:Javascript 接口的实现
原文地址:http://www.cnblogs.com/jones-c/p/3754690.html