/*
接口:提供一种说明一个对象应该有哪些方法的手段
js中有三种方式实现接口:
1 注释描述接口
2 属性检测接口
3 鸭式辨型接口
*/ /*
1 注释描述接口: 不推荐
优点: 利用注解,给出参考
缺点:纯文档约束,是一个假接口,
程序不能检查实现接口对象是否实现所有接口方法
*/ /**
* interface Composite{
* function a();
* function b();
* }
*/
// CompositeImpl implements Composite
var CompositeImpl = function(){
//业务逻辑
};
CompositeImpl.prototype.a = function(){
//业务逻辑
};
CompositeImpl.prototype.b = function(){
//业务逻辑
}; /*
2 属性检测接口:
优点:能够检测实现哪些接口
缺点:没有完全脱离文档,
不能检测是否实现每个接口里的所有方法
*/
/**
* interface Composite{
* function a();
* }
*
* interface FormItem(){
* function b();
* }
*/
// CompositeImpl implements Composite,FormItem
var interfacesImpl = function(){
//在实现类内部用一个数组保存要实现的方法名
//通常这个属性名是团队中规定好的
this.implementsInterfaces = ["Composite","FormItem"];
};
CompositeImpl.prototype.a = function(){
//业务逻辑
};
CompositeImpl.prototype.b = function(){
//业务逻辑
}; //专门为这个实现对象写一个检测函数,传入实例对象,用于检查实力对象是否实现了所有接口
function checkImplements(obj){
//调用检查方法 obj是否实现两个接口,如果没有都实现则抛出异常
if(!isImplements(obj,"Composite","FormItem")){
throw new Error("接口没有全部实现!");
}
//接收一个参数obj是要检查的对象
function isImplements(obj){
//arguments对象能够获取实际传入函数的所有参数的数组
//传入的第0个参数是要检查的对象,所以从1开始检查
for(var i = 1; i < arguments.length ; i++){
//接收接口中每个接口的名字
var interfaceName = arguments[i];
//一个标记,是否实现这个接口,默认没有
var foundFlag = false;
//循环查询传入实例对象的实现接口数组 以检查是否全部实现
for(var j = 0 ;j <obj.implementsInterfaces.length;j++){
//如果 实现了这个接口 就修改标记跳出循环
if(obj.implementsInterfaces[j]==interfaceName){
foundFlag = true;
break;
}
}
//如果遍历实现接口数组之后没找到 就返回false
if(!foundFlag){
return false;
}
}
//如果都找到了 返回true
return true;
}
} //使用实力对象并检测
var o = new interfacesImpl();
checkImplements(o); //不会抛出异常 因为正确实现了两个接口
//如果在写interfacesImpl内的implementsInterfaces列表的时候少写了,那么就会在检查函数中抛出异常 /*
3 鸭式辨型法:(目前开发中使用的方式)
实现思想: */ //1 接口类 Class Interface
/**
* 接口类需要的参数:
* 1 接口的名字
* 2 要实现方法名称的数组
*/
var Interface = function( name , methods ){
//判断参数个数
if(arguments.length!=2){
throw new Error("接口构造器参数必须是两个!");
}
this.name = name;
this.methods = [];
for(var i = 0;i<methods.length;i++){
if( typeof methods[i] !== "string" ){
throw new Error("接口实现的函数名称必须是字符串!");
}
this.methods.push(methods[i]);
} };
//2 准备工作:
// 2.1 实例化接口对象 传入接口名 和 要实现的方法数组
var CompositeInterface = new Interface("CompositeInterface",["add","remove"]);
var FormItemInterface = new Interface("FormItemInterface",["update","select"]); // 2.2 实现接口的类
//CompositeImpl implementes CompositeInterface ,FormItemInterface
var CompositeImpl = function(){ };
// 2.3 实现接口的方法
CompositeImpl.prototype.add = function(obj){
alert("add...");
};
CompositeImpl.prototype.remove = function(obj){
alert("remove...");
};
CompositeImpl.prototype.select = function(obj){
alert("select...");
};
//在这里少实现一个方法 下面检测是否全部实现了接口方法
// CompositeImpl.prototype.update = function(obj){
// alert("update...");
// };
// 实例化 实现接口的对象
var c = new CompositeImpl(); //3 检验接口里的方法是否全部实现
// 如果检验通过 继续执行;如果不通过抛出异常;
Interface.ensureImplements = function(obj){
// 如果接收到参数小于2 说明 传参出错了,只传入一个参数,,没有传入实现的接口
if(arguments.length<2){
throw new Error("接口检查方法的参数必须多余两个!");
}
//获得要见测的接口实现对象之后的参数 各个接口
for(var i = 1,len = arguments.length;i<len;i++){
var instanceInterface = arguments[i]; //获取当前这个接口
//判断接收到的是不是接口的对象 如果不是 抛出异常
if( instanceInterface.constructor !== Interface){
throw new Error("接口检测函数必须传入接口对象!");
}
//检查实例化接口的对象是不是实现了接口里的所有方法
// 当前接口对象里的每一个方法
for(var j = 0 ; j<instanceInterface.methods.length;j++){
var methodName = instanceInterface.methods[j]; //接收到了字符串的方法名
//如果obj里面没有有methodName这个方法 或者有这个属性但是不是函数 就抛出异常
if(!obj[methodName] || typeof obj[methodName] !== "function"){
throw new Error("接口方法"+ methodName +"没有实现!");
}
}
} };
//传入要检查的类,和他要实现的所有接口对象
Interface.ensureImplements(c ,CompositeInterface ,FormItemInterface );
c.add();

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

  1. C#接口的三种实现方式

    转自原文C#接口的三种实现方式 public interface MyInterface { /// 下面三个方法的签名都是 /// .method public hidebysig newslot ...

  2. 初见Ajax——javascript访问DOM的三种访问方式

    最近好啰嗦 最近在一间小公司实习,写一些小东西.小公司嘛,人们都说在小公司要什么都写的.果真是. 前端,后台,无论是HTML,CSS,JavaScript还是XML,Java,都要自己全包了.还好前台 ...

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

    JavaScript声明全局变量的三种方式   JS中声明全局变量主要分为显式声明或者隐式声明下面分别介绍. 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为 ...

  4. 【转】SVG与HTML、JavaScript的三种调用方式

    原文:https://www.cnblogs.com/guohu/p/5085045.html SVG与HTML.JavaScript的三种调用方式 一.在HTMl中访问SVG的DOM 1 2 3 4 ...

  5. JavaScript 闭包的详细分享(三种创建方式)(附小实例)

    JavaScript闭包的详细理解 一.原理:闭包函数--指有权访问私有函数里面的变量和对象还有方法等:通俗的讲就是突破私有函数的作用域,让函数外面能够使用函数里面的变量及方法. 1.第一种创建方式 ...

  6. javascript中构造函数的三种方式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. JavaScript中创建对象的三种方式!

    JavaScript中创建对象的三种方式! 第一种 利用对象字面量! // 创建对象的三种方式! // 1 对象字面量. var obj = { // 对象的属性和方法! name: 'lvhang' ...

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

    每种编程语言学到数组的时候,都会讲到排序算法,当时学C语言的时候,卡在排序算法.今天来总结一下javascript中如何实现三种排序算法. 1.冒泡排序(默认升序排列哦) 原理: 冒泡排序的原理,顾名 ...

  9. python笔记-20 django进阶 (model与form、modelform对比,三种ajax方式的对比,随机验证码,kindeditor)

    一.model深入 1.model的功能 1.1 创建数据库表 1.2 操作数据库表 1.3 数据库的增删改查操作 2.创建数据库表的单表操作 2.1 定义表对象 class xxx(models.M ...

随机推荐

  1. Xamarin Forms中WebView的自适应高度

    在Xamarin.Forms中,WebView如果嵌套在StackLayout和RelativeLayout中必须要设置HeightRequest和WidthRequest属性才会进行渲染.可是在实际 ...

  2. jquery ajax 返回的json对象 新增属性值(干货)

    $.ajax({ type:"GEt'; url:"你的地址", data:{"你的字段","字段值"} success:funt ...

  3. NMEA0183

    NMEA简介 NMEA是全国海洋电子协会(National Marine Electronics Association):国际海上电子协会(National Marine Electronics A ...

  4. Mycat 分片规则详解--单月小时分片

    实现方式:单月内按照小时拆分,最小粒度是小时,一天最多可以有24个分片,最少1个分片,下个月从头开始循环 优点:使数据按照小时来进行分时存储,颗粒度比日期(天)分片要小,适用于数据采集类存储分片 缺点 ...

  5. spring boot高性能实现二维码扫码登录(下)——订阅与发布机制版

     前言 基于之前两篇(<spring boot高性能实现二维码扫码登录(上)——单服务器版>和<spring boot高性能实现二维码扫码登录(中)——Redis版>)的基础, ...

  6. oracle--dba和表的备份与恢复

    数据库管理员 每个oracle数据库应该至少有一名数据库管理员(dba),对于一个小的数据库,一个dba就够了,但是对于一个大的数据库可能需要多个dba分别担负不同的管理职责,那么一个数据库管理员的主 ...

  7. xpath获取下一页,兄弟结点的妙用

    第一页的情况: 第四页的情况 : 文章的链接:  http://tech.huanqiu.com/science/2018-02/11605853_4.html 从上面我们可以看到,如果仅仅用xpat ...

  8. IO流回顾与总结第一篇之字节流与字符流的操作。。。。。

    一.引言 趁着年后的这点时间,抓紧点时间回顾下javase中的IO流,以往都是用到那些常用的IO类,这次来个全点的,有不对的地方还请大神指正一下,做到坚持写博的习惯来...... 回归正题,IO流顾名 ...

  9. 【总结】关于YUV-RGB格式转换的一些个人理解

    这段时间一直在研究YUV的格式问题例如YUV422.YUV420,在网上搜索了很多这方面的资料,发现很多资料讲的东西是重复的,没有比较深入的讲解,所以看了之后印象不是很深,过了一段时间之后又对它们有了 ...

  10. Beta冲刺NO.3

    Beta冲刺 第三天 1. 昨天的困难 1.昨天的困难主要集中在对Ajax的使用上,不熟悉这种语法,所以也就浪费了时间,导致昨天的批量删除没有完全完成. 2.由于之前的网页构造style很乱,导致修改 ...