架构型设计模式-同步模式
模块化: 将复杂的系统的分解成高内聚、低耦合的模块,使系统的开发变得可控、可维护。可拓展、提高模块的复用率
同步模块模式-SMD(Synchronous Module Definition)请求发出后,无论模块是否存在,立即执行后续的逻辑,实现模块开发对模块的立即引用
模块的管理器和创建方法
1 /** 2 * @param str模块路由 3 * @param fn模块方法 4 */ 5 // 定义模块管理器单体对象 6 var F = F || {} 7 8 F.define = function(str, fn){ 9 // 解析模块路由 10 var parts =str.split('.'), 11 // old当前的模块的的祖父模块, parent 当前模块的父模块 12 // 如果在闭包中,为了屏蔽对模块的直接访问,建议将模块添加给闭包内部私有变量 13 old = parent = this, 14 // i 模块层级,len模块层级长度 15 i = len = 0; 16 17 // 如果第一个模块是模块管理器单体对象,则移除 18 if(parts[0]==='F'){ 19 parts = parts.slice(1) 20 } 21 // 屏蔽对define与module模块方法重写 22 if(parts[0] === 'define' || parts[0] === 'module'){ 23 return 24 } 25 // 遍历路由模块并定义每层模块 26 for(len = parts.length; i < len; i++){ 27 // 当模块不存在当前模块 28 if(typeof parent[parts[i]] === 'undefined'){ 29 // 声明当前的模块 30 parent[parts[i]] = {}; 31 } 32 // 缓存下一层的祖父模块 33 old = parent; 34 // 缓存下一层的父模块 35 parent = parent[parts[i]] 36 37 } 38 39 // 如果给定的模块方法则定义该模块方法 40 if(fn){ 41 // 此时i等于parts.length, 顾减一 42 old[parts[--i]] = fn(); 43 44 } 45 46 // 返回模块管理器单体对象 47 return this 48 }
创建模块 F.string模块
1 F.define('string', function(){ 2 // 3 return { 4 // 5 trim: function(str){ 6 return str.replace(/^\s+|\s+$/g, ''); 7 // return str 8 } 9 } 10 })
来测试一下
console.log('=====', ' 11测试用例 ', '=====', F.string.trim(' 11测试用例 '),'====')
对于模块的回调函数,我们也可以一构造函数的形式返回接口,比如创建DOM模块,其中包括DOm()获取元素方法等
1 F.define('dom', function(){ 2 // 简化 3 var $ = function(id){ 4 $.dom = document.getElementById(id); 5 console.log(document.getElementById(id)) 6 return $ 7 } 8 9 $.html = function(html){ 10 if(html){ 11 this.dom.innerHTML = html; 12 return this; 13 }else{ 14 return this.dom.innerHTML; 15 } 16 } 17 18 return $; 19 })
测试一下
F.dom('test').html()
console.log('!!!!!', F.dom('test').html())
F.define('dom.addClass'); F.dom.addClass = function(type, fn){ return function(className){ if(!~this.dom.className.indexOf(className)){ // 简单添加类 this.dom.className +=''+className } } }();
// 测试用例 F.dom('test').addClass('test')
模块的调用
// 模块的调用 F.module = function(){ // 将参数转换为数组 let args = [].slice.call(arguments), // 获取回调执行函数 fn = args.pop(), //获取依赖模块, 如果是args[0]是数组,则依赖模块为 args[0]。否依赖模块为args parts = args[0] && args[0] instanceof Array ? args[0] : args, // 依赖模块列表 modules =[], // 模块路由 modIDs = '', // 依赖模块索引 i = 0, // 依赖模块长度 ilen = parts.length, // 父模块, 模块路由层级索引,模块路由有层级长度 parent, j, jlen; //遍历依赖模块 while(i < ilen){ // 如果模块路由 if(typeof parts[i] === 'string'){ // 设置当前模块父对象(F) parent = this // 解析模块路由, 并屏蔽掉模块父对象 modIDs = parts[i].replace(/^F\./, '').split('.') // for(j = 0, jlen = modIDs.length; j < jlen; j++){ // 重置父模块 parent = parent[modIDs[j]] || false } // 将模块添加到依赖模块列表中 modules.push(parent); //如果是模块对象 } else { // 直接加入依赖模块列表中 modules.push(parts[i]) } // 取下一个依赖模块 i++; } // 执行回调执行函数 fn.apply(null, modules) }
View Code
1 F.module(['dom', document], function(dom, doc){ 2 // 通过dom模块设置元素内容 3 dom('test').html('new add!'); 4 // 通过document设置body元素背景色 5 doc.body.style.background = 'red' 6 }); 7 F.module('dom', 'string.trim', function(dom, trim){ 8 // 9 let html = dom('test').html(); 10 let str = trim(html); 11 console.log('*'+html+'*', '*'+str+'*') // 12 })