JavaScript设计模式学习一之接口

看完了《JavaScript王者归来》,在图书馆找了《JavaScript设计模式》来看,之前设计模式方面的书看过:《Head First 设计模式》、《设计模式之禅》,GOF的《Design Patterns: Elements of Reusable Object-Oriented Software》看了一部分。记得以前没这些基础的时候,看《JavaScript设计模式》简直是不知道作者在说什么。

言归正传:

准确的说,JavaScript没有类的概念,都是对象,JavaScript是基于面向对象的语言,但是《JavaScript设计模式》的作者们非要说JavaScript是面向对象的(也不知道是不是翻译的过程中问题)。用JavaScript来描述那些设计模式的时候,需要通过JavaScript的一些特性(比如说闭包、原型)来模拟Java、C++等面向对象语言的一些特性(比如说类、接口、继承、public、private)。


书中说了三种模拟Interface的方法

第一种:用注释描述接口

我觉得这个就是一种内部约定,直接说“我实现了XX接口”,在语言上我个人觉得一点约束力都没有,这真不应该拿出来说,有点滥竽充数的感觉。

第二种:用属性检查模仿接口

需要一个叫做implements()的函数进行检查

 function implements(object){
	for(var i=1;i<arguments.length;i++){
		var interfaceName = arguments[i];
		var interfaceFound = false;
		for(var j=0;j<object.implementsInterfaces.length;i++){
			if(object.implementsInterfaces[j] == interfaceName){ 	//implementsInterfaces保存了接口定义的方法的名称
				interfaceFound = true;
				break;
			
			}
		
		}
		if(!interfaceFound){
			return false; 	//接口没有找到
		}
	}
	return true;
 }


这是《JavaScript设计模式》书中的一部分代码,作者的描述是这样的:

这种方法有几个优点。它对类所实现的接口提供了文档说明。如果需要的接口不在一个类宣称支持的接口之列,你会看到错误消息。通过利用这些错误,你可以强迫其他程序员声明这些接口。这种方法的主要缺点在于它并未确保类真正实现了自称实现的接口。只知道它是否说自己实现了接口,在创建一个类声明它实现了一个接口,但后来在实现该接口方法所规定的方法时却漏掉其中的某一个,找一个错误很常见,此时所有的检查都能通过,但那个方法却并不存在,这将在代码中埋下一个隐患。


随即引出了第三中方法:用鸭式辨型模仿接口

原理:如果对象具有与接口定义的方法同名的所有方法,那么就可以认为它实现了这个接口。

首先需要一个接口类Interface

 var Interface = function(name ,methods){
	……
 }
接受两个参数:接口名称,方法名


这个Interface类还有一个静态方法 ensureImplements()

 Interface.ensureImplements = function(object){
	……
			
}

实际用法是这样的:

 
 var Composite = new Interface('Composite',['add','remover','getChild']);
 var FormItem = new Interface('FormItem',['save']);
 
 var CompositeForm = function(id,method,action){
	……
 
 }
 
 function addForm(formInstance){
	ensureensureImplements(formIntance,Composite,FormItem);
	//This function will throw an error if a required method is not implemented
	……
 }

最后作者采用第一种和第三种方法实现接口,代码如下:

 var Interface = function(name,methods){
	if(arguments.length!=2){
		throw new Error("Interface constructor called with"+arguments.length+
		"arguments,but expected exactly 2.");
	}
	this.name = name;
	this.methods=[];
	for(var i=0, len = methods.length;i<len;i++){
		if(type methods[i] !=='string'){
			throw new Error("Interface constructor expects method names to be passed in as a string");
		}
		this.methods.push(methods[i]);
	}
 };
 
 Interface.ensureImplements = function(object){
	if(arguments.length<2){
		throw new Error("Function Interface.ensureImplements call 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 instance 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 implements the"+interface.name+"interface.Method"+method+"was not found");
			}
		
		}
	
	};
 


JavaScript在我之前乃至现在的印象中,他就是应用在浏览器客户端的的一个脚本语言,主要的应用对象是浏览器,他需要这么大费周章的去模拟类似java的特性吗?有这个需求吗?我现在还没发现,以后可能能发现。

设计模式在我的理解就是四个字:解耦、复用。

可能是我现在需求还没那么高,,没办法理解设计模式在JavaScript里作用



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值