浅析 MVC

266 阅读3分钟

浅析 MVC

1. MVC 三个对象分别做什么,给出伪代码示例

  • M是modal(数据模型)的简称,它是用于操作所有数据
  • V是view(视图)的简称,它是用于负责所有UI界面
  • C是controller(控制器)的简称,它负责其他 cwwKLq.png

Model

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

View

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

Controller

  1. 控制器controller定义用户界面对用户输入的响应方式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据model上的改变。
  2. 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() { 自动绑定事件 }

}

2. EventBus

解决模块之间通信的问题,view组件层面,父子组件、兄弟组件通信都可以使eventbus处理.

on: 监听事件的变化

监听数据的变化,如果数据有变化,直接render(再次将变化后的数据渲染到页面)

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)//储存数据
    }

off:解绑事件

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

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

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];
}

通过哈希表将事件全部抽出来后代码简洁许多,且重复率也减少;这就是表驱动编程。

4. 模块化

  1. 将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起
  2. 块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信

好处

  • 避免命名冲突(减少命名空间污染)
  • 更好的分离, 按需加载
  • 更高复用性
  • 高可维护性