浅析 MVC

118 阅读4分钟

MVC 介绍


MVC 最开始是后端的一种软件架构方式,它将一个软件分为三个模块,Model:模型、View:视图和 Controller:控制器。

  • Model:控制器 —> 数据管理,主要负责数据和服务器进行交互,将请求到的数据发给 Controller

  • View:视图 —> 负责用户界面,HTML 渲染

  • Controller:控制器 —> 负责监听并处理 View 事件,更新和调用 Model ,也负责监听 Model 的变化(Model 从服务器获取数据),并更新 ViewController 控制其他所有流程

  • M —> Model: 数据部分

  • V —> View: 用户界面

  • C —> Controller: 业务逻辑

三个模块的伪代码


Model

Model = {
    data: { 程序需要操作的数据或信息 },
    create: { 增数据 },
    delete: { 删数据 },
    update(data) { 
       Object.assign(m.data, data) //使用新数据替换旧数据
       eventBus.trigger('m:upate') // eventBus触发'm:update'信息, 通知View刷新 
    },
    get:{ 获取数据 } 
}

View

View = {
    el: 需要刷新的元素,
    html: `<h1>M V C</h1>....显示在页面上的内容`
    init(){
        v.el: 需要刷新的元素
    },
    render(){ 刷新页面 }
}

Controller

Controller = {
   init(){
      v.init() // View初始化
      v.render() // 第一次渲染
      c.autoBindEvents() // 自动的事件绑定
      eventBus.on('m:update', () => { v.render() }) // 当eventBus触发'm:update'时View刷新
   },
   events:{ 事件以哈希表方式记录 },
   method() {
      data = 改变后的新数据
      m.update(data)
   },
   autoBindEvents() { 自动绑定事件 }
}

EventBus


EventBus 主要用来解决三个模块之间的通信问题,比如说当 Model 模块中的数据发生更新,触发了 EventBus 上的某个事件,而 Controller 恰好在监听这个事件,当这个事件触发时,Controller 就知道 Model 中的数据发生了更新了,从而做出一些反应

EventBus 常用的一些 API

  • EventBus.on,事件的订阅
EventBus.on(eventName,callback)  
//参数1:事件名称  参数2:事件函数
//判断当前事件名称是否存在,如果不存在则创建一个key值为事件名称
//value为一个数组 将callback push到数组中
 
const eventList = {};
EventBus.on = (eventName,callback)=>{
     if(!eventList[eventName]){
         eventList[eventName] = [];
     }
     eventList[eventName].push(callback)
}
  • EventBus.off,解绑事件
EventBus.off(eventName,[callback])  
//参数1:事件名称  参数2:[事件函数]
//判断当前事件名称是否存在,如果存在继续判断第二个参数是否存在,如果存在则找到相//对应的下标 然后将函数在数组中移除
//如果不存在则将整个数组清空
 
const eventList = {};
EventBus.off = (eventName,callback)=>{
    if(eventList[eventName]){
          if(callback){
                 let index = eventList[eventName].indexOf(callback);
                 eventList[eventName].splice(index,1)
           }
    }else{
           eventList[eventName].length = 0; 
    }
}
  • EventBus.trigger ,用于触发事件
EventBus.trigger(eventName,[params]) 
//参数1:事件名称 参数2:[需要传递的参数]
//判断当前事件的名称是否存在,如果存在则遍历数组,得到所有的函数,
//并执行。然后将params当做实参传递到函数中去
const eventList = {};
EventBus.trigger = (eventName,params)=>{
    if(eventList[eventName]){
         let arr = eventList[eventName];
         arr.map((cb)=>{
             cb(params)
         })
    }
}

表驱动编程是做什么的


表驱动法就是一种编程模式,从表里面查找信息而不使用逻辑语句。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。对简单的情况而言,使用逻辑语句更为容易和直白。但随着逻辑链的越来越复杂,查表法也就愈发显得更具吸引力。 ——《代码大全》

如果某个函数需要接受一个参数,这个参数的值不固定,函数需要根据参数的值执行对应的逻辑,我们可以用 if...else 轻松解决,但如果需要判断的参数非常多,就需要写很多的判断逻辑,这样不但写着累,可阅读性也非常低,我们可以用一个哈希表代替

const list={
    "小明":10,
    "小白":14,
    //等等...
}
function age2(name){
    if(name in list){
        console.log(name+"的年龄是"+list[name])
    }else{
        console.log("查无此人")
    }
}

我是如何理解模块化的


模块化可以大大降低程序耦合性,每个模块各司其职,就算有一个模块出错,也不会影响到其他模块的正常运行,打个并不形象的比方,如果把一个房间作为程序,里面的电器就是不同的模块,洗衣机负责洗衣服,热水器负责烧水,台灯负责照明,就算洗衣机坏了,也不会影响你用热水器洗澡,用台灯照明

另外,模块化拥有很好的复用性,这意味着我们可以将一些枯燥且重复的操作都封装到一个模块中,当我们需要的时候直接引用,可以大大提高我们的开发效率

参考文章