# 同步模块模式

模块化:将复杂的系统分解成高内聚、低耦合的模块,使系统开发变得可控、可维护、可拓展、提高模块的复用率。

同步模块模式:请求发出后,无论模块是否存在,都立即执行后续的逻辑。

# 模块管理器与创建方法

对于同步模块调度,首先要创建模块,如果没有模块那么谈什么调度呢。

我们首先定义一个模块管理器对象 F,然后为其创建一个模块定义方法 define。

F.define(String, Function)

// syncModuleManager.js
((global) => {

  const F = F || {};
  F.define = function (str, fn) {
    const parts = str.split(".") // "a.b.c" ==> [a, b, c]
    let old = parent = this;
    let i = len = 0;
    // 不让定义在 F 对象上
    if (parts[0] === "F") {
      parts = parts.slice(1)
    }
    // 保护内置方法不被重写
    if (parts[0] === "deine" || parts[0] === "module") {
      return false;
    }
    // 遍历模块 a, b, c ==>  a:{ b:{ c:{ } } } 
    for (len = parts.length; i < len; i++) {
      if (typeof parent[parts[i]] === 'undefined') {
        parent[parts[i]] == {}
      }
      old = parent
      parent = parent[parts[i]]
    }
    // 定义模块方法
    if (fn) {
      old[parts[--i]] = fn()
    }
    return this
  }

})(global)

# 创建模块

比如我们创建一个 DOM 模块,其中包括 dom() 获取元素,html() 可以获取或设置元素 innerHTML内容的方法等等等。

// syncModuleDOM.js
F.deinfe("dom",function (){
  // 返回一个构造器方法
  const $ = function (id){
    $.dom = document.getElementById(id)
    return $ // 方便链式调用
  }
  $.html = function (html){
    if(html){
      this.dom.innerHTML = html;
    }else {
      return this.dom.innerHTML
    }
  }
  return $;
})

F.define("dom.addClass",function (){
  // 返回方法
  return function (className){
    if(!~this.dom.className.indexOf(className)){
      this.dom.className += ' ' + className
    }
  }
})
<div id="test">test</div>
F.dom("test").html()
F.dom("test").html("hello")
F.dom("test").addClass("test")

# 调用模块方法

要使用模块我们需要创建一个使用模块的方法,或者说引入模块的方法

F.module = function () {
  const args = [].slice.call(arguments)
  // 获取回调方法
  const fn = args.pop()
  // 区分数组还是单个模块
  parts = args[0] && args[0] instanceof Array ? args[0] : args
  const modules = [];
  const modIDs = "";
  let parent;
  let i = 0;
  // 多个模块
  while (i < parts.length) {
    if (typeof parts[i] === "string") {
      // parent --> F
      parent = this;
      modIDs = parts[i].replace(/^F\./, "").split(".")
      for (let j = 0; j < modIDs.length; j++) {
        // 移动 parent 指针
        parent = parent[modIDs[j]] || false
      }
      // 找到模块实际对应的方法,将其加入列表
      modules.push(parent)
    } else {
      modules.push(parts[i])
    }
    i++
  }
  // 执行回调,传入模块列表
  fn.apply(null, modules)
}

# 学以致用

使用时

  • 单个模块 F.module(String, Function)
  • 多个模块 F.module(Array, Function)
F.module(["dom", document], function (dom, doc){
  dom("test").html("new add content !");
  doc.body.style.background = "black";
})

# 总结

模块化开发是分治的思想,实现对复杂系统的分解,使系统随着其功能的增加而变得可控、可拓展、可维护。

随着系统功能的增加,模块的数量也随之增加,模块的开发成本减少,但模块的接口却也随之增加了,接口的使用成本和开发维护成本就随之增加,所以合理的模块分割显得尤为重要。