zoukankan      html  css  js  c++  java
  • 从头开始写框架(二):孕育框架的种子_下

    终于来到最后一节了!

    今天我们会把我们的种子模块完成,之后就可以开始扩展我们的框架了!是不是开始有些兴奋了呢?

    先来回顾一下之前的内容:

    我们搞定了命名空间、多库共存机制、模块扩展机制。

    恩,跟我们开始定好的目标只差一小步了。现在我们来完成它

    首先,先来用模块扩展机制为我们的命名空间添加方法,我们来简单的添加三个方法:多库共存、toString、toNumber

    function(module, exports, require){
    
    	var _Cvm = window.Cvm , _$ = window.$;
         //在exports上面注册方法,来为命名空间扩展功能
    	exports.reName=function(deep){ //冲突处理机制
    
    		window.$ = _$;
    
    		if(deep){
     
            window.Cvm = _Cvm; 
     
        	};
    
        	return Cvm;
    
    	};
    
    	exports.toString=function(val){ //toString
    		return val.toString();
    	}
    
    	exports.toNumber=function(str){ //toNumber
    		var n = Number(str);
    		return !isNaN(n) ? n : "";
    	}
    
    }
    

      

    OK,那么我们定义好了一个模块,之后在工厂方法中将模块的方法返回给命名空间:

    return (function(modules){// 用来注册和生产用户调用的模块和方法,参数为模块的集合
    
    		var moduleDepot = {} //缓存区
    
    		function require(moduleId){
    
    			if(moduleDepot[moduleId])
    				return moduleDepot[moduleId];  //直接调用缓存
    
    			var module = {
    				exports:{},
    				moduleId:moduleId,
    				loaded:false
    			};
    
    			modules[moduleId].call(module.exports, module, module.exports, require); //获得模块
    
    			moduleDepot[moduleId] = module; //添加缓存
    
    			module.loaded=true;
    
    			return module.exports //返回模块
    
    		};
    
    		return require(0); // 返回第0个模块
    

      

    测试一下:

    <script src="../jquery-1.8.3.min.js"></script>
    <script src="Cvm.js"></script>
    <script>
    //先引入一个命名空间同样为$的JQ
    
    var _ = $.reName();
    
    var a = _.toString(123);
    var b = _.toNumber("456");
    
    
    console.log(typeof a) //string
    console.log(typeof b) //number
    </script>
    

      

    OK,到现在为止,基本上我们的种子模块就完成了!

    只差一个问题:我们只把第0个模块注册到了命名空间上,但是我们不可能把所有功能都写在同一个模块里,因为这样的话就无法多人去编写框架了,而且对以后的维护升级都是一个巨大的屏障。

    我们需要一个中介者来完善模块的扩展机制:

    function(module, exports, require){
    
    	var _ = require(1); //将扩展功能的模块请求过来
    
    	var extend = _.extend; //获得扩展的方法
    
    	var p = {}; // 中介者
    
    	extend(p , require(2)); // 为中介者注册方法
    	
    	module.exports = p; //最终返回中介者
    },
    //*  0-end  *//
    //
    //
    //*  1-start  *//
    function(module, exports){ // 扩展模块
    
    	exports.extend = function(to , from){
    		var keys = Object.keys(from);
    		var i = keys.length;
    
    		while(i--){
    			to[keys[i]] = from[keys[i]];
    		}
    		return to;
    	}
    
    },
    //*  1-end  *//
    //
    //
    //*  2-start  *//
    function(module, exports, require){ //多库共存模块
    	var _Cvm = window.Cvm , _$ = window.$;
    
    	exports.reName=function(deep){ //多库共存
    
    		window.$ = _$;
    
    		if(deep){
     
            window.Cvm = _Cvm; 
     
        	};
    
        	return Cvm;
    
    	};
    },
    //*  2-end  *//
    

      

    使用中介者p来扩展功能,然后返回这个中介者。此时这个中介者已经拥有所有扩展后的功能了,所以即使我们在种子模块里并没有请求多库共存的模块,但因为它已经被扩展给了中介者,所以最后我们还是可以得到这个模块的所有功能。

    这样,我们的种子模块就彻底宣告完成了。你可以在此基础上,任意的扩展你的命名空间,也可以很方便的完成模块之间的依赖引用。

    完整代码:

    !function(global , target){
    
    	if(typeof global !== 'undefined'){
    
    		global.Cvm = global.$ = target();
    
    	}else{
    
    		throw new Error("Cvm requires a window with a document")
    
    	}
    
    }(typeof window !== 'undefined'? window : this , function(){ //工厂是一个函数
    
    	return (function(modules){// 用来注册和生产用户调用的模块和方法,参数为模块的集合
    
    		var moduleDepot = {} //缓存区
    
    		function require(moduleId){
    
    			if(moduleDepot[moduleId])
    				return moduleDepot[moduleId].exports;  //直接调用缓存
    
    			var module = {
    				exports:{},
    				moduleId:moduleId,
    				loaded:false
    			};
    
    			modules[moduleId].call(module.exports, module, module.exports, require); //获得模块
    
    			moduleDepot[moduleId] = module; //添加缓存
    
    			module.loaded=true;
    
    			return module.exports //返回模块
    
    		};
    
    		return require(0);
    
    })([
    //*  0-start  *//
    function(module, exports, require){
    
    	var _ = require(1);
    
    	var extend = _.extend;
    
    	var p = {}; // 中介者
    
    	extend(p , require(2));
    	
    	module.exports = p;
    },
    //*  0-end  *//
    //
    //
    //*  1-start  *//
    function(module, exports){
    
    	exports.extend = function(to , from){
    		var keys = Object.keys(from);
    		var i = keys.length;
    
    		while(i--){
    			to[keys[i]] = from[keys[i]];
    		}
    		return to;
    	}
    
    },
    //*  1-end  *//
    //
    //
    //*  2-start  *//
    function(module, exports, require){
    	var _Cvm = window.Cvm , _$ = window.$;
    
    	exports.reName=function(deep){ //多库共存
    
    		window.$ = _$;
    
    		if(deep){
     
            window.Cvm = _Cvm; 
     
        	};
    
        	return Cvm;
    
    	};
    },
    //*  2-end  *//
    ])
    })
    

      

    最后说两句:

    模块扩展机制的好处是:方便多人协作完成一个框架的编写。

    因为编写一个大型、功能完备的框架毕竟不是一个容易的事情,需要很多人很长时间去完成的,所以模块扩展机制的好处在此就有很大的发挥空间。

    而模块的编写就像拼装玩具,把各个独立的功能拼接在一起,就变成了一个完整而强大的功能。

    实际上,编写框架就是这样一个过程:在工作中不断积累业务需求与解决方法,并且不停的抽象你的代码。当你的代码累积到一定的数量级后,自然而然的就会开始编写框架。

    至于之后的功能,我们以后再来展开!

  • 相关阅读:
    delphi 数据导出 进度条自己生成
    在存储过程中编写正确的事务处理代码(SQL Server 2000 & 2005)
    在Delphi中如何获得SQL中存储过程的返回值?
    object-c中管理文件和目录:NSFileManager使用方法
    Delphi中动态链接库(DLL)的建立和使用
    开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供)
    wince 程序无法执行的原因
    如果我写一个播放器
    busybox配置
    switch case被人忽视的一点!zt
  • 原文地址:https://www.cnblogs.com/BlueQ/p/5066430.html
Copyright © 2011-2022 走看看