浅析 MVC 和模块化编程

254 阅读3分钟

一、理解 MVC 和模块化编程

M 的英文是 Model,代表数据模块,主要用于封装数据和数据的处理方法,V 的英文是 View,是视图的意思,主要负责用户界面;C 的英文是 Controller,控制器的意思,主要负责用户监听,然后,调用 M 和 C 更新数据和视图。

MVC 是一种将代码进行重构的模块化编程方法,可以提高代码的开发效率维护效率。之所以使用模块化的编程方式,主要原因是 JS 代码越来越庞大,从而导致代码的开发和维护都较为困难,而模块化编程则可以将庞大的代码分解成一个个微小的模块,每个模块负责实现一个功能,每个模块提供不同的 API,从而提高开发效率和维护效率。同时,使模块化编程的方法,可以减少很多重复冗余的代码,也让代码结构变得更加稳定简洁

const m = {
  data: x,
  create(){},
  delete(){},
  updata(){},
  get(){}
}

const v = {
  el: null,  // 相当于一个容器,放置动态渲染 HTML
  html: `<div>...<div>`,  
  init(){}, 
  render(){}  // 渲染
}

const c = {
  init(){
    ...some code
    // 自动监听对象 v
    // 监听 eventBus 事件,当该事件被触发时执行相应操作
  },
  event: {}, // 一个哈希表
  method1(){},
  method2(){},
  method3(){},
  autoEvent(){
    ...some code
    // v 上的事件触发时,会调用 m 上的方法,从而更改 m.data
  }  // 自动监听事件
}

MVC 运行时的逻辑示意图.png

二、EventBus 和表驱动编程

通过 jQuery 创建 EventBus 主要是为了可以调用其中的三个 API,分别为 trigger()on()off(),它们的作用分别为触发、监听和关闭 EventBus 事件,从而可以在 m、v、c 三个对象之间实现通信。

const eventBus = $(window) // $ 为 jquery 
const m = { 
    data: x 
    update(){
        eventBus.trigger('m:changed')  // 触发,m:changed 为 eventBus 事件。
    } 
} 

cosnt c = { 
    add(){ 
        m.data.x += 1 
        eventBus.on('m:changed', (){  
            c.render() 
        })   // 监听;关闭监听则把 on 改成 off 
    } 
}

当然,由于 EventBus 的三个方法会被频繁用到,所以一般都会通过原型(类)和继承的方法,把这三个方法放到最顶层,让每个对象的原型链最顶层都具有这三个方法。下面,是通过类的方式自定义 EventBus,并使 View 继承 EventBus。

class EventBus{
    constructor() {
        this._eventBus = $(window)
      }

    on(eventName, fn) {
        return this._eventBus.on(eventName, fn)  //绑定事件
      }

    trigger(eventName, data) {
        return this._eventBus.trigger(eventName, data)  //自动触发事件
      }

    off(eventName, fn) {
        return this._eventBus.off(eventName, fn)  //撤销事件绑定
      }
}

class View extends Eventbus{
    constructor(***)
    super()  // 此后,View 类便继承了 EventBus 的三个方法
}

表驱动编程主要是将数据结构类似代码放到哈希表中,然后通过遍历或者其它方法对哈希表中的数据进行操作的一种编程方式。表驱动编程省略了很多逻辑语句,使得很多重复沉冗的代码变得稳定简洁

// 正常编程方式
function weekday(day) {  // 假设 day 的初始值为 1
  if (day % 7 === 0){ 
    return '星期天'
  } else if (day % 7 === 1) {
    return '星期一'
  } else if (day % 7 === 2) {
    return '星期二'
  } else if (day % 7 === 3) {
    return '星期三'
  } else if (day % 7 === 4) {
    return '星期四'
  } else if (day % 7 === 5) {
    return '星期五'
  } else if (day % 7 === 6) {
    return '星期六'
  }
}

// 表驱动编程方式
function week(days){
  let weekdays=['星期天','星期一','星期二','星期三','星期四','星期五','星期六']
  return weekdays[days % 7]
}