interfaces
接口是一种指定对象应该有哪些方法的技术,他不关心方法如何实现。
why?
设计模式作者说:“我们应该基于接口编程,而不是基于实现编程”。基于接口编程的好处是:实现相同接口的对象,可以互换,而不影响功能实现。
接口是具有自说明性质的,接口告诉开发人员类实现了什么方法,这让类的使用变得简单些了。同时,如果你会使用实现了某个接口的类,那么,所有实现了该接口的类,你也会使用了。
接口还有利于大项目中,多人合作的交流
how?js 怎么样去实现interface呢?
传统OO语言,通过interface 和 implements 关键字实现接口。其中,interface 关键字,实现对要实现的方法的说明;implements 关键字,说明类要实现接口。所以,我们通过js来模拟这两个关键字,来实现接口功能
what? 怎么做
文章介绍了三种方法。
1 用注释。当然interface 和 implements 都在注释里面
如:
/* interface domHandle {
function add(el){};
function remove(el){};
}
*/
var domForm = function(){};
// Implement the domHandle interface
domForm.prototype.add = function(el){};
用注释来实现接口,优点是简单,文档充分,没有多余的代码,性能好。但他却没有检测申称实现接口的类是否真的实现了,所有的保证都是口头的。
2 属性检测
首先,类显示申明自己实现的接口。
再次,在使用时,通过检测对象的类是否显示申明过要使用的接口,来确定对象是否是合格的参数。
/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
}
interface FormItem {
function save();
}
*/
var CompositeForm = function(id, method, action) {
this.implementsInterfaces = ['Composite', 'FormItem'];
...
};
...
function addForm(formInstance) {
if(!implements(formInstance, 'Composite', 'FormItem')) {
throw new Error("Object does not implement a required interface.");
}
...
}
// The implements function, which checks to see if an object declares that it
// implements the required interfaces.
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.
}
这个方法的主要缺点是:类只是说自己实现了接口,但不能确定他正在去实现了接口中的函数。
3 duck typing
如果一个对象包含所有在接口中声明的方法,那么这个对象就可以说实现了该接口
// Interfaces.
var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
var FormItem = new Interface('FormItem', ['save']);
// CompositeForm class
var CompositeForm = function(id, method, action) {
...
};
...
function addForm(formInstance) {
ensureImplements(formInstance, Composite, FormItem);
// This function will throw an error if a required method is not implemented.
...
}
这个方法区别与其他两种方法的地方是:他没有注释,所有的要求都是强制的。相对与其他两种,他也有缺点。一个是类没有说明自己实现了哪些接口,造成理解困难;他需要几个帮助的函数:interface和ensureImplements,可能造成性能问题;他只检测类中有函数名,而没有对参数个数和类型进行检测。
具体的interface 和 ensureImplements 请参考原书