浅析MVC

211 阅读3分钟

什么是MVC

  • M 就是 model,即数据模型,负责数据相关的任务,包括对数据的增删改查。
  • V 就是 view,即视图层,即用户能看得到的界面。
  • C 就是 Controller,即控制器,负责监听用户事件,然后调用 M 和 V 更新数据和视图。 除却上述定义外,每个人对MVC的理解都不尽相同。MVC并没有一个明确的做法,实际将代码变的结构化的一种抽象概念就可以理解为MVC
//代码示例
// 数据相关都放到m
const Model= {
    data:{},    //绑定数据
    init: function(){},     //增删改查
    add: function(){},
    delete: function(){},
    get: function(){}
}
// 视图相关都放到v
const View={
    el:'',  //挂载元素
    init: function(){},    //初始化
    template:'',            //模板
    render: function(){}   //渲染函数
}
// 其他都放c
const controller = {
    init(): function{},         //初始化
    bindEvents: function(){},   //绑定事件
}

EventBus是什么

1.什么是EventBus

EventBus 也就是观察者模式,它主要用于对象或模块之间的通讯。例如MVC中,Model 数据模型 和 View 视图模型不知道彼此数据,但又需要通讯,就可以使用EventBus进行通讯。

怎么使用EventBus

EventBus我们在运用的时候通常是这么来引入的:

const eventBus = $(window)

eventBus 提供了 on、off 和 trigger 等 API,off用于取消监听

trigger 用于触发事件

const m = {
  ....
  update(data) {
    Object.assign(m.data, data)
    eventBus.trigger('m:updated')  // 通知一下view层,我已经更新了数据,view该开始工作了
    localStorage.setItem('n', m.data.n)
  },
  ....
}

on 用于监听事件,off用于取消监听

const c = {
  init(container) {
    v.init(container)
    v.render(m.data.n) // view = render(data)
    c.autoBindEvents()
    eventBus.on('m:updated', () => {   // controller会用 on  监听事件,
      //然后通知 view 模型去重新渲染页面
      v.render(m.data.n)
    })
  },
  ...
}

表驱动编程

当我们需要判断非常多的情况下做不同的事情的时候,我们需要写很多的if...else...语句,这样无疑非常难看且多余。而表驱动编程可以将条件判断的数据存到一个哈希表中,再根据不同情况在哈希表中取值从而达到同if...else...语句相同的作用

例:如果要一个可以返回每个月中天数的函数(为简单起见不考虑闰年),用if else:

function iGetMonthDays(iMonth) {
let iDays;
if(1 == iMonth) {iDays = 31;}
else if(2 == iMonth) {iDays = 28;}
else if(3 == iMonth) {iDays = 31;}
else if(4 == iMonth) {iDays = 30;}
else if(5 == iMonth) {iDays = 31;}
else if(6 == iMonth) {iDays = 30;}
else if(7 == iMonth) {iDays = 31;}
else if(8 == iMonth) {iDays = 31;}
else if(9 == iMonth) {iDays = 30;}
else if(10 == iMonth) {iDays = 31;}
else if(11 == iMonth) {iDays = 30;}
else if(12 == iMonth) {iDays = 31;}
return iDays;
}

用表驱动(包括闰年判断):

const monthDays = [
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
[31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
]
function getMonthDays(month, year) {
let isLeapYear = (year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0) ? 1 : 0
return monthDays[isLeapYear][(month - 1)];
}
console.log(getMonthDays(2, 2000))

由此可见,表驱动编程要比if....else....方法效率高很多

模块化

我们可以把代码模块化比喻成电脑主机。CPU、显卡、内存、硬盘等等硬件都是相应的单独模块,每个模块各司其职,互相独立却又通过主板连接在一起。这样每次电脑升级只需要更换相应的模块就可以,大大降低了成本。而我们的代码也是一样,通过不同节点、结构的不同功能,划分出不同的模块,每个模块独立存在却又相互配合,组合成我们最终的成品。这样可以很大程度上降低代码耦合度,减少重复代码,提高代码重用性。并且使得项目作品结构清晰,便于日后升级或维护