Javascript 中模拟接口的三种要领
1. 解释形貌
/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
}
interface FormItem {
function save();
}
*/
var CompositeForm = function(id, method, action) { // 定义接口类
...
};
// 为接口类增加要领
CompositeForm.prototype.add = function(child) {
...
};
CompositeForm.prototype.remove = function(child) {
...
};
CompositeForm.prototype.getChild = function(index) {
...
};
CompositeForm.prototype.save = function() {
...
};
此种要领不容易范例恪守,属于顺序文档领域,对接口的商定恪守端赖自发。然则易于完成,不需分外的类或函数。
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.");
}
...
}
// 搜检一个对象是不是完成了须要的接口
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; j++) {
if (object.implementsInterfaces[j] == interfaceName) {
interfaceFound = true;
break;
}
}
if (!interfaceFound) {
return false; // 未找到接口
}
}
return true; // 一切接口都找到了
}
此要领的长处是对类完成的接口供应了文档申明,假如须要的接口未完成则会报错。瑕玷在于不能保证类是不是真正完成了接口,只知道它是不是说本身完成了接口,纵然代码未将接口完成也能经由过程搜检,这将在代码中留下隐患。
3. 鸭式辨型
鸭式辨型的意义就是,假如对象具有与接口定义的要领同名的一切要领,那末就认为它完成了这个接口。
// 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);
...
}
ensureImplements
函数最少接收两个参数,一个是须要搜检的对象,其他为针对此对象须要搜检是不是完成的接口。详细搜检体式格局则是搜检对象是不是完成了接口所声明的一切要领。
此要领的瑕玷是缺少其他两种要领的自我形貌性,须要一个辅佐类Interface
和一个辅佐函数ensureImplements
。而且它只体贴要领称号而不搜检参数称号、数量、范例等。
Interface
类
综合第一及第三种接口完成体式格局,Interface
类的定义可认为:
// Constructor
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 (typeof methods[i] !== 'string') {
throw new Error("Interface constructor expects method names to be " +
" passed in as a string");
}
this.methods.push(methods[i]);
}
};
// Static class method
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 methods = 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.");
}
}
}
};
依靠接口的设想形式
以下的设想形式依靠接口
1. 工场形式 保证临盆出来的对象完成了必需的要领。
2. 组合形式 将对象群体与构成对象同等对待。
3. 装潢者形式 透明地为另一对象供应包装,完成雷同的接口。
4. 敕令形式 一切的敕令对象都完成了统一批要领。