javascript定義接口有3種方式
1註解描述的方式
2屬性檢測的方式
3鴨式辨型的方式
//1註解描述的方式
//優點:程序員有一個參考
//缺點:還是屬於文檔的範疇,這種方式太鬆散了,沒有檢查接口的方法是否完全被實現的
/*
* interface Composite{
* function add(obj);
* function remove(obj);
* function update(obj);
* }
*/
//CompositeImpl implements Composite
var CompositeImpl = function() {
};
CompositeImpl.prototype.add=function(obj){};
CompositeImpl.prototype.remove=function(obj){};
CompositeImpl.prototype.update=function(obj){};
var c1 = new CompositeImpl();
var c2 = new CompositeImpl();
alert(c1.add==c2.add);
//第二種實現接口的方式,屬於屬性檢測的方式
/*
* interface Composite{
* function add(obj);
* function remove(obj);
* function update(obj);
* }
*
* interface FormItem{
* function select(obj);
* }
*/
//CompositeImpl implements Composite,FormItem
var CompositeImpl = function () {
//顯示的在類的內部接受所實現的接口
//一般來說是一個規範,我們項目經理:在類的內部定義一個數組(名字要固定)
this.implememtsInterfaces=['Composite','FormItem'];
};
CompositeImpl.prototype.add=function(obj){
alert("add...")
};
CompositeImpl.prototype.remove=function(obj){};
CompositeImpl.prototype.update=function(obj){};
CompositeImpl.prototype.select=function(obj){};
function checkCompositeImpl(instance){
//判斷當前對象是否實現了所有接口
if(!isImplements(instance,'Composite','FormItem')){
throw new Error("Object doesn't implement the required interface");
}
return true;
}
var comImpl = new CompositeImpl();
if(checkCompositeImpl(comImpl)){
comImpl.add();
}
//公用的具體的檢測方法,返回值類型boolean
//這個方法的主要目的:就是判斷實例對象有沒有實現相關的接口
function isImplements(object,interfaces){
//arguments對象獲得函數的實際參數
for(var i=1;i<arguments.length;i++){
//接受所實現的每一個接口的名字
var interfaceName = arguments[i];
//判斷此方法到底成功還是失敗呀
var interfaceFound=false;
for(var j=0;j<object.implememtsInterfaces.length;j++){
if(object.implememtsInterfaces[j]==interfaceName){
interfaceFound=true;
break;
}
}
if(!interfaceFound){
return false;
}
}
return true;
}
//實現接口的第三種方式:鴨式辨型法實現接口(最完美的javascript實現接口的方式)
//註解描述法,屬性檢測法
//鴨式辨型法實現的核心:一個類實現接口的主要目的:把接口裏的方法都實現(檢測方法)
//完全面向對象,代碼也實現統一,也解耦了
//一: 接口類 Class Interface ===> 實例化N多個接口
/*
* 接口類需要2個參數嗎?
* 參數1:接口的名字
* 參數2:接收方法名稱的集合(數組)
*/
var Interface = function(name,methods){
//判斷接口的參數個數
if(arguments.length != 2){
throw new Error("this instance interface constructor argument must be 2 length");
}
this.name = name;
this.methods=[];//定義一個內置的空數組對象,等待接收methods裏的元素(方法名字)
for(var i=0,len = methods.length; i < len; i++){
if(typeof methods[i] !== 'string'){
throw new Error("the interface method name is error!");
}
this.methods.push(methods[i]);
}
}
//二: 準備工作
// 1 實例化接口對象
var CompositeInterface = new Interface('CompositeInterface',['add','remove']);
var FormItemInterface = new Interface('FormItemInterface',['update','select']);
//CompositeImpl implements CompositeInterface,FormItemInterface
//2 具體的實現類
var CompositeImpl = function(){
}
//3 implements methods
CompositeImpl.prototype.add=function(obj){
alert("add...")
};
CompositeImpl.prototype.remove=function(obj){
alert("remove...")
};
CompositeImpl.prototype.update=function(obj){
alert("update...")
};
CompositeImpl.prototype.select=function(obj){
alert("select...")
};
//三: 檢驗接口裏的方法
//如果檢驗通過,不做任何操作,如果不通過,瀏覽器拋出error
//這個方法的目的,就是檢測方法的
Interface.ensureImplements=function (object) {
//如果檢測的方法接受的參數個數小於2個,參數傳遞失敗
if(arguments.length < 2){
throw new Error("Interface.ensureImplements method constructor arguments length must be > 2 ");
}
//獲得接口實例對象
for(var i = 1,len = arguments.length; i < len ; i++){
var instanceInterface = arguments[i];
//判斷參數是否是接口類的類型
if(instanceInterface.constructor !== Interface){
throw new Error("the arguments constructor not be interface class");
}
//循環接口實例裏的每一個方法
for(var j = 0; j < instanceInterface.methods.length;j++){
//用一個臨時變量,接受每一個方法的名字(注意是字符串)
var methodName = instanceInterface.methods[j];
//object[key]就是方法
if(!object[methodName] || typeof object[methodName] !== 'function'){
throw new Error("the method '" + methodName +"' is not found");
}
}
}
}
var c1 = new CompositeImpl();
Interface.ensureImplements(c1,CompositeInterface,FormItemInterface);
c1.add();