javascript学习(7)——[知识储备]接口

在正式学习设计模式之前,我们先坐下基本的知识储备,可能大多数java程序员和我一样,在没有深入学习js之前,也没有怎么听说过js竟然也有接口这么一说,其实是这样的,js的接口和js中的继承一样,由于js并不是严格的面向对象语言,所以也就只能是模仿面向对象语言来实现类似于面向对象语言中的接口。

在js中主要有三种实现接口的方式,分别是:

(1)注解的方法

(2)属性检验法

(3)鸭式变形法

下面我们一一介绍:

(1)注解的方法:

/**
 * 1.注释方法
 * 最简单,但是功能也是最弱的
 * 他利用inerface和implement"文字"
 * 把他们用注解的方式显示的表现出来
 */
(function(){
	/**
	 * 用注释来定义一个接口
	 * interface PersonDao(){
	 * 	function add(obj);
	 *  function remove(obj);
	 *  function find(id);
	 * }
	 */
	//我们用注释的方式来实现他
	/**
	 * PersonDaoImpl implement interface
	 */
	var PersonDaoImpl = function(){
		
	}
	PersonDaoImpl.prototype.add = function(obj){
		//..
	}
	PersonDaoImpl.prototype.remove = function(obj){
		//..
	}
	PersonDaoImpl.prototype.find = function(id){
		//..
	}
	/**
	 * 千万不要感觉他是没有任何意义的
	 * 1.大型的项目靠得就是规范和标准
	 * 2.这样的写法会交你的程序员在没有写实现之前有充分时间做代码的设计和架构
	 * 3.缺点:要人为的遵守
	 */
})()

(2)属性检验法

/**
 * 属性检验法
 */
(function(){
	/**
	 * 用注释来定义一个接口
	 * interface PersonDao(){
	 * 	function add(obj);
	 *  function remove(obj);
	 *  function find(id);
	 * }
	 */
	//我们用注释的方式来实现他
	var PersonDaoImpl = function(){
		this.implementInterface = ["PersonDao"];		
	}
	PersonDaoImpl.prototype.add = function(obj){
		alert(obj)
		//..
	}
	PersonDaoImpl.prototype.remove = function(obj){
		//..
	}
	PersonDaoImpl.prototype.find = function(id){
		//..
	}	
	function addObj(obj){
		var PersonDao = new PersonDaoImpl();
		//开始检查
		if(!impl(PersonDao,"PersonDao")){
			throw new Error("类PersonDaoImpl没有实现接口PersonDao");
		}else{
			PersonDao.add(obj);
		}
	}
	addObj("USCAPT.COM");
	/**
	 * 他接受的是一个不定参数
	 */
	function impl(Object){
		//遍历出入对象的属性
		for(var i=1;i<arguments.length;i++){
			var interfaceName = arguments[i];
			var interfaceFound = false;
			for(var j=0;j<Object.implementInterface.length;j++){
				if(Object.implementInterface[j] == interfaceName){
					interfaceFound = true;
					break;
				}
			}
			if(!interfaceFound){
				return false;
			}
		}
		return true;
	}
	
	
	
})()

(3)鸭式变形法

/**
 * 3.鸭式变形法
 * 这个方法来源于一个国外的老头他有一个名言(jim)
 * "像鸭子一样走路并且会嘎嘎叫的东西就是鸭子"
 * 换言之
 * 如果对象具有与接口定义的方法名字的同命所有方法 那么我就认为你就是实现本接口
 */
(function(){
	//定义一个接口类
	var Interface = function(name,methods){
		if(arguments.length != 2){
			alert("interface must have two paramters...");
		}
		this.name = name;//这个是接口的名字
		this.methods = [];//定义个空数组来装载函数名
		for (var i = 0; i < methods.length; i++) {
			if(typeof methods[i] != "string"){
				alert("method name must is String ...")
			}else{
				this.methods.push(methods[i])
			}
		}
	}
	//定义接口的一个静态方法来实现接口与实现类的直接检验
	//静态方法不要写成Interface.prototype.* 因为这是写到接口原型链上的
	//我们要把静态的函数直接写到类层次上
	Interface.ensureImplements = function(object){
		if(arguments.length<2){
			alert("必须最少是2个参数");
			return false;
		}
		//遍历
		for (var i = 1; i < arguments.length; i++) {
			var inter = arguments[i];
			//如果你是接口就必须是Interface类型的
			if(inter.constructor != Interface){
				throw new Error("if is interface class must is Interface type");
			}
			//遍历函数集合并分析
			for (var j = 0; j < inter.methods.length; j++) {
				var method = inter.methods[j];
				//实现类中必须有方法名字 和 接口中所有的方法名项目
				if(!object[method] || typeof object[method] != "function"){
					throw new Error("实现类并且没有完全实现接口中的所有方法...");
				}
			}
		}
	}
	//应用
	//定义自己的接口
	var GridMananger = new Interface("GridMananger",["add","remove","list"]);
	var FormMananger = new Interface("FormMananger",["save"])
	
	function commManager(){
		//先实现方法
		this.add = function(){
			alert("ok")
		}
		this.remove = function(){}
		this.list = function(){}
		this.save = function(){}
		//检验
		Interface.ensureImplements(this,GridMananger,FormMananger)
	}
	var c = new commManager();
	c.add();
	/**
	 * 接口的重要性
	 * 1.大型项目提高代码的灵活度
	 * 2.松耦合
	 * 3.在团队开发的时候,有写时候你在真正编码之前就可以写API(自己的类库)
	 * 那这类库就可以时候在进行实现
	 * 开始的时候我们就可以对整个项目是否可行,通过接口就可模拟出来
	 */
	
})()




原文地址:https://www.cnblogs.com/sunyingyuan/p/3686225.html