javascript设计模式一——接口

原创 2013年12月04日 10:24:04

 

JavaScript是弱类型语言,所以类型匹配问题很难追踪。同时,Js并没有像其他语言一样,提供内置的创建或实现接口的方法。这样,在我们进行对象转化的时候是很困难的。

 

不过,我们还是可以使用程序来模拟JavaScript Interface接口的实现。一般来说,模拟Interface的实现有如下三种方法:

 

注释法——将接口的定义写在注释中,大家能否小心注意,以实现接口的所有方法全凭自觉。

 

java中使用interface和implements关键字实现接口的

 

/*
interface Composite{
	function add(child);
	function remove(child);
	function getChild(index);
}

interface FormItem{
	function save();
}
*/

 

 

 

//模拟CompositeForm继承了Composite、FormItem接口
var CompositeForm = function(id,name,action){
	...
}

CompositeForm.prototype = {
	add:function(child){
		...
	},
	remove:function(child){
		...
	},
	getChild:function(index){
		...
	},
	save:function(){
		...
	}
}

 

备注:这种模仿并不是很好,它没有为确保CompositeForm真正实现了正确的方法集而进行检查,也不会抛出错误以告知程序中有问题。

 

 

属性检查法——自己说明我实现了哪些接口,一会儿你检查的时候记得检查我说我实现的接口里面,是否把我真正想要实现的接口全部实现了(这么别扭呢),总之就是自欺欺人

 

var CompositeForm = function(id, method, action) {
    //声明自己继承了Composite,FormItem接口
    this.implementsInterfaces = ['Composite', 'FormItem'];
   ...
};

function addForm(formInstance) {
    //判断formInstance是否继承了Composite,FormItem接口
    if(!implements(formInstance, 'Composite', 'FormItem')) {
        throw new Error("Object does not implement a required interface.");
    }
    ...
}

//判断当前对象是否继承了对象声明的接口
function implements(object) {
    for(var i = 1; i < arguments.length; i++) { // Looping through all arguments 
                                                // after the first one.
        var interfaceName = arguments[i];
        var interfaceFound = false;
        for(var j = 0; j < object.implementsInterfaces.length; j++) {
            if(object.implementsInterfaces[j] == interfaceName) {
                interfaceFound = true;
                break;
            }
        }
    
        if(!interfaceFound) {
            return false; // An interface was not found.
        }
    } 	
    return true; // All interfaces were found.
}

 

鸭式辨型法——如果对象具有与接口定义的方法同名的所有方法,那么久可以认为它实现了这个接口。

 

var Interface = function(name,methods){
	if(arguments.length!=2){
		throw new Error("Interface 的构造函数一定只能有两个参数")
	}
	this.name = name;
	this.methods = [];
	
	for(var i=0,len=methods.length;i<len;i++){
		if(typeof methods[i] !== "string"){
			throw new Error("Interface构造参数方法名称为string类型");
		}else{
			this.methods.push(methods[i]);
		}
	}
}

Interface.ensureImplements = function(object){
	//至少包含两个参数——继承接口的对象,对应的接口(至少含有一个)
	if(arguments.length<2){
		throw new Error("Function Interface.ensureImplements called with " + 
          arguments.length  + "arguments, but expected at least 2.");
	}
	
	for(var i=1,len=arguments.length;i<len;i++){
		//具体实现接口的对象
		var _interface = arguments[i];
		if(_interface.constructor !== Interface) {
            throw new Error("Function Interface.ensureImplements expects arguments "   
              + "two and above to be instances of Interface.");
        }
		
		//接口对应的参数
		for(var j = 0, methodsLen = _interface.methods.length; j < methodsLen; j++) {
			var method = _interface.methods[j];
            if(!object[method] || typeof object[method] !== 'function') {
                throw new Error("Function Interface.ensureImplements: object " 
                  + "does not implement the " + _interface.name 
                  + " interface. Method " + method + " was not found.");
            }
		}
		
	}
	
	
}

var Composite = new Interface("Composite",["add","remove","getChild"]);
var FormItem = new Interface("FormItem",["save"]);

//CompositeForm继承Composite、FormItem两个接口

/*提示缺少接口对象参数
var CompositeForm = new function(id, method, action){
}
Interface.ensureImplements(CompositeForm);
*/

/*提示没有实现Composite接口
var CompositeForm = new function(id, method, action){
}
Interface.ensureImplements(CompositeForm,Composite);
*/

/*提示没有实现Composite接口
var CompositeForm = new function(id, method, action){
	this.add=function(){};
	this.remove=function(){};
	//this.getChild=function(){};
}
Interface.ensureImplements(CompositeForm,Composite);
*/

/*正确显示
var CompositeForm = new function(id, method, action){
	this.add=function(){};
	this.remove=function(){};
	this.getChild=function(){};
}
Interface.ensureImplements(CompositeForm,Composite);
*/

/*
var CompositeForm = new function(id, method, action){
	this.add=function(){};
	this.remove=function(){};
	this.getChild=function(){};
	this.save=function(){};
}
Interface.ensureImplements(CompositeForm,Composite,FormItem);
*/

var CompositeForm = new function(id, method, action){
	this.add=function(){};
	this.remove=function(){};
	this.getChild=function(){};
	this.save=function(){};
	//用来验证当前对象是否实现了Composite,FormItem接口
	Interface.ensureImplements(this,Composite,FormItem);
}

 

 教程上的另外一个例子

ResultFormatter.prototype.renderResults = function() {
  var dateOfTest = this.resultsObject.getDate();
  var resultsArray = this.resultsObject.getResults();
  
  var resultsContainer = document.createElement('div');

  var resultsHeader = document.createElement('h3');
  resultsHeader.innerHTML = 'Test Results from ' + dateOfTest.toUTCString();
  resultsContainer.appendChild(resultsHeader);
  
  var resultsList = document.createElement('ul');
  resultsContainer.appendChild(resultsList);
  
  for(var i = 0, len = resultsArray.length; i < len; i++) {
    var listItem = document.createElement('li');
    listItem.innerHTML = resultsArray[i];
    resultsList.appendChild(listItem);
  }
  
  return resultsContainer;
};


// ResultSet Interface.

var ResultSet = new Interface('ResultSet', ['getDate', 'getResults']);

// ResultFormatter class, after adding Interface checking.

var ResultFormatter = function(resultsObject) {
  Interface.ensureImplements(resultsObject, ResultSet);
  this.resultsObject = resultsObject;
};

 

javascript通常建立接口的三种方式(彻底的明白了)

这篇文章叙述了javascript通常用的创建接口的方式,注释描述、属性检测,鸭式辩型,分别叙述了其中的优缺点,其中鸭式辩型最完美的实现了。。。...
  • js_admin
  • js_admin
  • 2017年05月01日 11:41
  • 1289

JavaScript调用COM接口说明

我们在开发COM组件给js调用时,需要提供给js的是COM接口的CLASSID,而不是组件的classid。如下为COM组件的一个idl文件:// FuckATL.idl : FuckATL 的 ID...
  • zhanghui_new
  • zhanghui_new
  • 2015年12月24日 14:55
  • 778

JavaScript-设计模式之接口的实现

在JS中,并没有真正意义上的接口,我们只能通过模拟的方式实现接口的效果,使用接口可以促进代码的重用,降低代码之间的耦合度,减少代码错误及查找错误原因,坏处就是加大代码量,而且并不能强制程序员实现接口。...
  • qq_32588349
  • qq_32588349
  • 2016年06月11日 00:23
  • 1327

JavaScript设计模式之接口

什么是接口 接口是提供了一种用以说明一个对象应该具有哪些方法的手段。尽管它可以表明这些方法的语义,但它并不规定这些方法应该如何实现。例如,如果一个接口包含有一个名为setName的方法,那么你有理由认...
  • jing_valora
  • jing_valora
  • 2016年06月01日 18:53
  • 212

JS的继承和接口

此工具函数没实际意义,只是鉴于EXT的extend方法不太好理解,写了一个简化的extend方法,帮助理解. /** * */ E = {}; E.extend = function(sub, ...
  • songzheng_741
  • songzheng_741
  • 2014年05月09日 20:50
  • 1701

面向对象在JavaScript中的接口实现

接口是面向对象编程的基础,它是一组包含了函数型方法的数据结构,与类一样,都是编程语言中比较抽象的概念。比如生活中的接口,机顶盒,人们利用它来实现收看不同频道和信号的节目,它犹如对不同类型的信息进行集合...
  • Tyro_java
  • Tyro_java
  • 2016年04月19日 19:17
  • 1708

编写restful接口时通过jsonview来控制输出json中字段的显示或者忽略

1:编写接口 package com.sh.daniel.controller; import java.util.ArrayList; import java.util.List; import ...
  • yang920106
  • yang920106
  • 2017年11月22日 14:25
  • 101

Atitit java c# php c++ js跨语言调用matlab实现边缘检测等功能attilax总结

Atitit java c# php c++ js跨语言调用matlab实现边缘检测等功能attilax总结   1.1. 边缘检测的基本方法Canny最常用了1 1.2. 编写matlab...
  • attilax
  • attilax
  • 2016年12月20日 22:07
  • 624

js跨域调用WebService的简单实例

步骤1. 在web.config中的system.web节点里加入 步骤2. webservice代码 using System; ...
  • zdhlwt2008
  • zdhlwt2008
  • 2016年12月29日 10:53
  • 4374

面向接口编程的优点

1 首先什么是面向接口编程? 面向接口编程就是先把客户的业务逻辑线提取出来,作为接口,业务具体实现通过该接口的实现类来完成。当客户需求变化时,只需编写该业务逻辑的新的实现类,通过更改配置文件(例如...
  • JJ_nan
  • JJ_nan
  • 2017年04月13日 19:04
  • 1341
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:javascript设计模式一——接口
举报原因:
原因补充:

(最多只允许输入30个字)