JavaScript设计模式-同步模块模式

99 阅读1分钟

前言

模块化:将复杂的系统分解成高内聚、低耦合的模块,是系统开发变得可控、可维护、可拓展、提高模块的复用率。 同步模块模式(SMD,Synchronous Module Definition):请求发出后,无论模块是否存在,立即执行后续的逻辑,实现模块开发中对模块的立即引用。

简易版实现define

define.js

//定义模块管理器单体对象
const F = {} ;
//模块管理器
F.define = function (str,fn) {
    let parts = str.split('.'),old = parent = this;
    if(parts[0] === 'F') {
        parts = parts.slice(1)
    }
    if(parts[0] === 'define' || parts[0] === 'module') {
        return 
    }
    for(let i =0,len = parts.length;i<len;i++) {
        if(!parent[parts[i]]) {
            parent[parts[i]] = {}
        }
        old = parent;
        parent = parent[parts[i]];
    }
    if(fn) {
        old[parts[parts.length-1]] = fn();
    }
    return this
}
//创建模块
F.define('dom',function() {
    var $ = function (id) {
        $.dom = document.getElementById(id);
        return $
    }
    $.html = function(html) {
        if(html) {
            this.dom.innerHTML = html;
            return this;
        } else {
            return this.dom.innerHTML;
        }
    }
    return $
})
F.define('dom.addClass',function() {
    return  function (className) {
        this.dom.className += ' ' + className;
        return this;
    }
})
//模块调用方法
F.module = function() {
    let args = [].slice.call(arguments),
    fn = args.pop(),modules = [],parent = this,modIDs = ''
    parts = args[0] && args[0] instanceof Array ? args[0] : args;
    for(let i =0;i<parts.length;i++) {
        if(typeof parts[i] === 'string') {
            modIDs = parts[i].replace(/^F\./,'').split('.')
            for(let j =0;j < modIDs.length;j++) {
                parent = parent[modIDs[j]] || false
            }
            modules.push(parent)
        } else {
            modules.push(parts[i])
        }
    }
    fn.apply(null,modules)
}

define.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./define.js"></script>
</head>
<body>
<div id="test" class="test">test</div>
<div id="module" class="module"></div>
</body>

<script>
F.dom('test').addClass('add-class').html('class')
F.module(['dom',document],function(dom,document){
   dom('module').addClass('module-class').html('module')
})
</script>