什么是MVC?

239 阅读4分钟

一.前言

MVC是一种架构设计模式,它通过关注点分离鼓励改进应用程序组织。在过去,MVC被大量用于构建桌面和服务器端应用程序,如今Web应用程序的开发已经越来越向传统应用软件开发靠拢,Web和应用之间的界限也进一步模糊。传统编程语言中的设计模式也在慢慢地融入Web前端开发。由于前端开发的环境特性,在经典MVC模式上也引申出了诸多MV*模式,被实现到各个Javascript框架中都有多少的衍变 。

mvc是为了解决页面代码重复问题,优化代码,
把重复的代码封装了,即放在一个函数里面去调用

image.png

二.MVC是什么

每个模块都可以写成三个对象,分别是M,V,C

1.M:Model,负责所有数据
  • 模型model用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。
  • 会有一个或多个视图监听此模型。一旦模型的数据发生变化,模型(M)将通知有关的视图(V)。
Model = {
    data: { 需要用到的数据 },
    create(): { 增数据 },
    delete(): { 删数据 },
    update() {更新数据},
    get():{ 获取数据 } 
}

2.V:View视图,负责所有UI界面
  • 视图view是它在屏幕上的表示,描绘的是model的当前状态。
  • 当模型的数据发生变化,视图相应地得到刷新自己的机会。
View = {
    el:null,
    html: `......` //视图模板
    init(){初始化页面},
    render(){ 刷新页面 }
}

3.C:Controller负责其他
  • 控制器controller定义用户界面对用户输入的响应方式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据model上的改变。
  • C里面主要是放一些事件的操作,如:click、on等等;这里面又设计到EventBus、表驱动编程等等。
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有哪有API,是做什么用的,给出伪代码示例

1.目的:解决模块之间通信的问题,view组件层面,父子组件,兄弟组件通信都可以用eventbus处理
2.API

on: 监听事件的变化

this.on('m:updated', () => {
      this.render(this.data)
    })

trigger:自动触发事件 当一个事件执行,eventBus触发m:updated

update(data) {
    Object.assign(m.data, data)//把传进来的data直接放在m.data上
    eventBus.trigger('m:updated')//通过trigger自动更新数据
    localStorage.setItem('n', m.data.n)//储存数据
    }

四.表驱动编程是做什么的

表驱动方法是一种使你可以在表中查找信息,而不必用逻辑语句(ifcase)来把他们找出来的方法。
事实上,任何信息都可以通过表来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。
但随着逻辑链的复杂,表就变得越来越富于吸引力了。
function translate(term) {
    if (term === '1') {
        return '一'
    } else if (term === '2') {
        return '二'
    } else if (term === '3') {
        return '三'
    } else {
        return '???'  
    }
}

// 如果想添加一个新的名词翻译,需要再添加一个if-else逻辑,例如:
function translate(term) {
    if (term === '1') {
        return '一'
    } else if (term === '2') {
        return '二'
    } else if (term === '3') {
        return '三'
    } else if (term === '4') {   
        // 此处添加了一个新的名词翻译
        return '四'
    } else {
        return '???'  
    }
}

表驱动编程:

function translate(term) {
    let terms = {
        '1': '一',
        '2': '二',
        '3': '三'
    }
    return terms[term];
}

// 如果想添加一个新的名词翻译,只需要在terms中添加一个新的表项,不需要修改整个逻辑
function translate(term) {
    let terms = {
        '1': '一',
        '2': '二',
        '3': '三'
        '4': '四'   // 添加一个新的名词翻译
    }
    return terms[term];
}

总结:通过哈希表将事件全部抽出来后代码就会简洁很多,这,就是表驱动编程。

五.如何理解模块化的

  • 将一个复杂的程序依据一定的规则封装成几个块,并进行组合在一起
  • 块的内部数据与实现是私有的,只是向外部暴露了一些
模块化的好处:
  1. 避免命名冲突(减少命名空间污染)
  2. 更好的分离, 按需加载
  3. 更高复用性
  4. 高可维护性