浅析MVC

32 阅读4分钟

MVC是什么

每一个模块可以写成三个对象,分别是M、V、C M——Model(数据模型),负责操作所有数据 V——View(视图),负责所有UI界面 C——Controller(控制器),负责其他

其中涉及到的一些抽象思维

  • 抽象思维1 最小知识原则 引入一个模块需要引入HTML、CSS、JS 需要知道的东西越少越好,模块化为这一点奠定了基础 但是这样做刚开始页面会是空白的,没有内容没有样式 可以添加载入动画或者骨架图或者站位内容
  • 抽象思维2 以不变应万变 每个模块都可以用m+v+c来写,每个模块都这样写,不用思考类似需求怎么写了 但是有时会有多余用不到的代码,遇到特殊情况时难以变通
  • 抽象思维3 view = render(data) 比起操作DOM对象,直接render更为容易,只要改变data就能得到对应的view 但是render渲染会比DOM更加浪费性能
  • 抽象思维4 表驱动编程 表指的是哈希表 表驱动编程可以减少重复代码,只讲重要的信息放在表里,然后利用表来编程(数据结构)
  • 抽象思维5 事不过三 同样的代码写三遍,应该抽成一个函数 同样的属性写三遍,应该做成共有属性(原型或类) 同样的原型写三遍,应该用继承
  • 抽象思维6 俯瞰全局 eventbus 负责事件通信 把所有的对象看成点,实现点与点的通信

Model:是应用程序中用于处理应用数据逻辑的部分。 用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法,会有一个或多个视图监听此模型。一旦模型数据发生变化,模型将通知有关视图。

const m = {
  data: {数据A},
  create() {},
  delete() {},
  update(data) {
        Object.assign(m.data,data)//用新数据替换旧数据
        eventBus.trigger('m:update')//eventBus触发'm:update'信息,通知View刷新界面
},
  get() {数据A}
}

View:是应用程序处理应用数据显示的部分。 它是在屏幕上面表示,描绘的是Model当前的状态。当模型的数据发生变化,相应的得到刷新自己的机会。

const v = {
  el: 需要刷新的元素,  
  html: `
       body里面的内容
`,
  init(container) {
    v.el = $(container)
  },
  render(n) {刷新页面}
}

Controller:是应用程序处理人机交互的部分。 Controller定义用户界面对用户输入的响应式,起到不同层面间的组织作用,用于控制应用程序的流程,它处理用户的行为和数据Model上的变化。

const c = {
  init(container) {
        v.init()//初始化View
        v.render()//第一次渲染页面
        c.autoBindEvents()//自动的事件绑定
        eventBus.on('m:update',()=>{v.render()}//当enentsBus触发'm:update'是View刷新
    },
  events: {},   //事件以哈希表的方式记录存储
  add() {},
  minus() {},
  mul() {},
  div() {},
  autoBindEvents() {自动绑定事件}
}

EventBus

  • on : 监听事件
  • trigger(emit) : 触发事件
  • off : 取消监听 用于模块间的通讯,view组件层面,父子组件、兄弟组件通信都可以使eventbus处理。
const eventBus = $(window)
eventBus.trigger('m:update') // 自动触发事件update
eventBus.on('m:update', () => {console.log('触发';)}) //监听事件 然后执行函数


表驱动编程

表驱动编程的意义在于逻辑与数据的分离

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

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

显而易见,容易了很多。根本不用修改代码逻辑。


模块化的理解

  • 模块化可以避免阻断。每个模块之前互相独立,互不影响,削弱了不同模块之间的联系,不影响其他模块的调用,此外其中一个模块产生了bug也不会影响到其他模块。这样子可以更好的优化和重构代码,方便维护。
  • 如果是多人协作开发,模块化可以有效避免代码覆盖和冲突的问题。