javascript设计模式开篇:Javascript 接口的实现
javascript语言不像java、 c#、 c++等面向对象语言那样有完备的接口支持,在javascript中,接口的实现有三种方式,分别为注释描述、属性检查、鸭式变形。注释描述实现起来最为简单,但是,接口约定的遵守纯靠自觉,而且也没有很好的度量措施,说到底,它主要还是属于程序文档范畴。其实,类是否申明自己支持哪些接口并不重要,只要它具有这些接口中的方法就行了。鸭式变形(这个名称来自James Whitcomb Riley的名言:"像鸭子一样嘎嘎叫的就是鸭子")正式基于这种认识。
下面来谈谈javascript中接口的具体实现策略。(基于鸭式变形,用的也是最多的哦~~)
* 接口类构造函数,接受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');
}
}
};
编写出上述代码挺简单,主要思路就是检测传入参数的类型和名称。看看某个具体实现类有没有实现所定义的接口中的那些function。。
下面给出一个调用接口的例子吧~
//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 接口的实现的更多相关文章
- JavaScript设计模式 Item 2 -- 接口的实现
1.接口概述 1.什么是接口? 接口是提供了一种用以说明一个对象应该具有哪些方法的手段.尽管它可以表明这些方法的语义,但它并不规定这些方法应该如何实现. 2. 接口之利 促进代码的重用. 接口可以告诉 ...
- JavaScript设计模式之一Interface接口
如何用面向对象的思想来写JavaScript,对于初学者应该是比较难的,我们经常用的JQuery其实也是用面向对象的思想去封装的,今天我们来看看如何在Javascript中用Interface,在C# ...
- Javascript设计模式笔记
Javascript是越来越厉害了,一统前后端开发.于是最近把设计模式又看了一遍,顺便做了个笔记,以方便自己和他人共同学习. 笔记连载详见:http://www.meteorcn.net/wordpr ...
- 【JavaScript设计模式系列---开篇预览】
转:http://www.cnblogs.com/Darren_code/archive/2011/08/31/JavascripDesignPatterns.html 2011-08-31 23:5 ...
- 《javascript设计模式》--接口
关于javascript设计模式书中的接口,记录如下 //TODO 增加了一个判断条件,可以只在生产环境中调用 接口var Interface = function(name,methods){ i ...
- 21种JavaScript设计模式最新记录(含图和示例)
最近观看了<Javascript设计模式系统讲解与应用>教程,对设计模式有了新的认识,特在此做些记录. 一.UML 文中会涉及众多的UML类图,在开篇需要做点基础概念的认识.以下面的图为例 ...
- 《JavaScript设计模式 张》整理
最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...
- 《JavaScript设计模式与开发实践》整理
最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...
- 常用的Javascript设计模式
<parctical common lisp>的作者曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型 ...
随机推荐
- 利用matlab写一个简单的拉普拉斯变换提取图像边缘
可以证明,最简单的各向同性微分算子是拉普拉斯算子.一个二维图像函数 f(x,y) 的拉普拉斯算子定义为 其中,在 x 方向可近似为 同理,在 y 方向上可近似为 于是 我们得到满足以上三个 ...
- [环境配置]Ubuntu 16.04 源码编译安装OpenCV-3.2.0+OpenCV_contrib-3.2.0及产生的问题
1.OpenCV-3.2.0+OpenCV_contrib-3.2.0编译安装过程 1)下载官方要求的依赖包 GCC 4.4.x or later CMake 2.6 or higher Git GT ...
- Unity游戏AI记录(2d横板为例)
using System.Collections;using System.Collections.Generic;using UnityEngine; public class GeneralPeo ...
- [咸恩静][Love effect]
歌词来源:http://music.163.com/#/song?id=31877654 作曲 : Monster Factory/양승욱 [作曲 : Monster Factory/yang-seu ...
- ElasticSearch5.6.1 + 中文分词(IK)
在安装ElasticSearch 需要先安装java 的 jdk 可以通过 命令来确认是否已经安装了 java -version 如果没有安装可以使用 yum 直接安装通过. 先通过命令查看yum源 ...
- PAT 甲级 1079 Total Sales of Supply Chain
https://pintia.cn/problem-sets/994805342720868352/problems/994805388447170560 A supply chain is a ne ...
- Navicat Premium和Navicat for MySQL哪个好用?
之前在Navicat官网下载了Navicat Premium和Navicat for MySQL使用.Navicat官网产品下载地址:https://www.navicat.com.cn/produc ...
- SpringBoot(十四)_springboot使用内置定时任务Scheduled的使用(一)
为什么使用定时? 日常工作中,经常会用到定时任务,比如各种统计,并不要求实时性.此时可以通过提前设置定时任务先把数据跑出来,后续处理起来更方便. 本篇文章主要介绍 springboot内置定时任务. ...
- 5Java异常处理
五.异常 异常概念总结: 练习一:异常的体系 问题: 1. 请描述异常的继承体系 2. 请描述你对错误(Error)的理解 3. 请描述你对异常(Expection的理解) ...
- suse11/12关闭防火墙
suse11关闭操作为:service SuSEfirewall2_setup stopservice SuSEfirewall2_init stop 取消开机启动防火墙:chkconfig SuS ...