浅述MVC

195 阅读3分钟

MVC历史

MVC模式最早由Trygve Reenskaug在1978年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构。MVC模式的目的是实现一种动态的程式设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式透过对复杂度的简化,使程序结构更加直观。软件系统透过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。专业人员可以依据自身的专长分组:

  • 模型(Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。

  • 视图(View) - 界面设计人员进行图形界面设计。

  • 控制器(Controller)- 负责转发请求,对请求进行处理。

经典MVC模式

MVC在Javascript中的样式

Model(模型)

他们不关心用户界面层或表示层,而是代表应用程序可能需要的独特数据形式。当模型发生更改时(例如,当更新时),它通常会通知其观察者(例如,我们将简要介绍的视图,概念)发生了更改,以便他们可以做出相应的反应。

// 伪代码示例
const m = {
data:{
    // 数据相关 
 }
 creat(){}  // 增
 delete(){}  // 删
 update(data){  // 改
     Object.assign(m.data,data) //将data的属性全部赋值给m.data
 }
 get(){}   // 查
}

View(视图)

视图是模型的可视化表示,提供了当前状态的过滤视图。

// 伪代码示例
const v {
    el: // 容器,判断渲染条件
    html:` `  // html
    init(){
          // 初始化
    }
    render(){
        if(v.el.children.length !== 0){
             // 清空页面
        }
        //  重新渲染页面
    }
}

Controller(控制器)

控制器是模型和视图之间的中介,当用户操作视图时,控制器通常负责更新模型。

// 伪代码示例
const v {
    init(){
        v.init()
        c.autoBindEvents() // 执行事件
    }
    // hashTable,
    events:{
        key1 : value1
        key2 : value2
    }
     // 事件响应
    value1(){}
    value2(){}
   autoBindEvents(){
    // 遍历数组,找到对应元素
       for(let key in c.events){
          const value = c[c.events[key]]
          const part1 =  ...  // 获得对应字符串
          const part2 =  ...
           v.el.on(part1,part2,value)
       }
   }
}

viue = render(model) // 所有的视图都是数据的再渲染

表驱动编程

表驱动法(Table-Driven Approach),简单讲是指用查表的方法获取值。 我们平时查字典以及念初中时查《数学用表》找立方根就是典型的表驱动法。在数值不多的时候我们可以用逻辑语句(if 或case)的方法来获取值,但随着数值的增多逻辑语句就会越来越长,此时表驱动法的优势就显现出来了。

示例

  events: {
  // 将我们要绑定的事件以key-value的形式放入表中
  // 以第一个为例
  // document.quretSelector('#add1').addEventListenter('cilck',()=>{})的原生api就很复杂,即使jquery也同样
    'click #add1': 'add', 
    'click #minus1': 'minus',
  },
  add() {
    m.update({n: m.data.n + 1})
  },
  minus() {
    m.update({n: m.data.n - 1})
  },
  // 我们遍历一边events,找到key,将它用数组的api分解成我们需要的字符串,比如下例我分解成part1='click',part2='#add1',对用的value就对应'add1(){}'函数
  autoBindEvents() {
    for (let key in c.events) {
      const value = c[c.events[key]]
      const spaceIndex = key.indexOf(' ')
      const part1 = key.slice(0, spaceIndex)
      const part2 = key.slice(spaceIndex + 1)
      v.el.on(part1, part2, value)
    }
  }

EventBus

简化组件间的通信

  • 对发送和接受事件解耦
  • 可以在Activity,Fragment,和后台线程间执行
  • 避免了复杂的和容易出错的依赖和生命周期问题

代码更加简洁

更快

更轻量