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>的作者曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型 ...
随机推荐
- 关于使用单片机读取外部电压ADC阻抗匹配的问题
单片机的基准电压一般为3.3V,如果外部信号超过了AD测量范围,可以采用电阻分压的方法,但是要注意阻抗匹配问题.比如,SMT32的模数输入阻抗约为10K,如果外接的分压电阻无法远小于该阻值,则会因为信 ...
- 软件测试----H模型
H模型将测试活动完全独立出来,形成一个完整的流程,同时将测试准备和测试执行清晰表现出来. 测试流程: --测试准备:所有测试活动的准备判断是否到测试就绪点. --测试就绪点:测试准入准则,即是否可以开 ...
- 如何干净的卸载docker
先上服务器环境信息: 卸载的原因: 宿主机过段时间就磁盘100%了,导致continart异常退出,后来找了很多解决方案,才发现是安装docker的时候有个配置文件错误(正常的应该是|Storage ...
- idou老师教你学Istio: 如何用Istio实现K8S Egress流量管理
本文主要介绍在使用Istio时如何访问集群外服务,即对出口流量的管理. 默认安装的Istio是不能直接对集群外部服务进行访问的,如果需要将外部服务暴露给 Istio 集群中的客户端,目前有两种方案: ...
- kudu 存储引擎简析
本文由 网易云发布. 1 概述 本文主要介绍kudu底层存储引擎的数据组织方式,先看整体结构如下: 一张表会分成若干个tablet , 每个tablet 包括MetaData 元信息及若干个RowS ...
- Alpha版总结会议——班级派
一.开会的过程 在周一下午上课的最后20分钟内,我们组进行了“班级派”的alpha版的总结会议.首先进行的是分析目前的版本情况,每个人说了自己的进度,包括已经完成的以及即将要完成的.随后是分析前段时间 ...
- nodeJs上传附件
两种方案: 这两种方案传参还是有区别额 在nodeJs中上传附件调用了 multer 的中间件,采用这个中间件来上传 首先是表单(前端部分): <!DOCTYPE html> <ht ...
- vue,react,angular本地配置nginx 环境单页面应用
一.起因:项目使用VUE,和react.构建单页面应用.在nginx的环境下只有一个index.html入口.这时候默认能够访问到vue,和react 路由 配置中的首页.内部连接也能够跳转但是不能给 ...
- Yii 框架的Rbac [权限控制]
转载自 xmlife 的博客 : http://blog.csdn.net/xmlife/article/details/50733451 1.首先我们要在配置文件的组件(component)里面配置 ...
- python基础教程1:入门基础知识
写在系列前,一点感悟 没有梳理总结的知识毫无价值,只有系统地认真梳理了才能形成自己的知识框架,否则总是陷入断片儿似的学习-遗忘循环中. 学习方法真的比刻苦"傻学"重要多了,而最重要 ...