浅谈MVC

374 阅读3分钟

【前言】

MVC是一种软件架构模式或者叫MVC框架;由模型(Model)、视图(View)、控制器(Controller)构成。该模式的目的是实现一种动态程序设计,能够简化后续程序的修改和扩展。

MVC三个对象

每个模块可以写成 M、V、C三个对象

  • M(Model:数据模型):负责操作所有的数据
  • V(View:视图):负责所有的ui界面
  • C(Controller):负责其他

需求:实现一个数的加减乘除;如图所示

使用MVC来实现这个需求(采用伪代码,理解思路即可)

  1. M对象操作所有的数据

数据相关的都放到m对象里

const m = {
	data:{数据n}
    create(){},
    delete(){},
    update(data){
    	Object.assign(m.data,data)//用新数据替换旧数据
        eventBus.trigger('m:update')//eventBus出发m:update事件,刷新界面
    },
    get(){}
}
  1. V对象负责所有的UI界面

视图相关都放到v里,


const v = {
	el: 存储需要渲染的页面,
    html:`
    	这里放html的内容
    `,
    init(container){
    	v.el = $(container)
    },
    render(n){刷新页面}
}
  1. C对象负责其他

其他操作处理放到c中


const c = {
	init(container){
            v.init()
            v.render()
            c.autoBindEvents()
            eventBus.on('m:update',()=>{v.render()},//当eventBus触发m:update时,刷新view
        },
        events:{事件}, //事件以哈希表的方式记录存储,涉及表驱动编程
        add(){+具体实现},
        minus(){-具体实现},
        mul(){*具体实现},
        div(){/ 具体实现},
        autoBindEvents(){自动绑定事件}
}

EventBus有哪些API

简单的说,就是一个以事件为驱动的消息服务总线

  1. api

EventBus基本API有on(监听事件), trigger(触发事件), off(取消监听)方法。

用于模块间的通讯,view组件层面,父子组件,兄弟组件通讯都可以使用eventBus处理

//EventBus.j代码
class EventBus{
    constructor(){
        this._eventBus =$(window)
    }
    on(eventName, fn){
        return this._eventBus.on(eventName,fn)
    }
    trigger(eventName,data){
        return this._trigger.tiggger(eventName,data)
    }
    off(eventName, fn){
        return this._eventBus.off(eventName,fn)
    }
}
export default EventBus


//new.js代码
import EventBus from 'EventBus.js'
const e =new EventBus()
e.on()
e.trigger()
e.off()

表驱动编程

表驱动是一种编程模式,从哈希表里面查找信息而不是使用逻辑语句(if...else...switch,可以减少重复的代码,把重要信息放到表里,然后利用表来编程,与逻辑语句相比较有着更稳定的复杂度)

例如

bindEvents(){
    v.el.on('click','#add1',()=>{
    m.data.n +=1
    v.render(m.data.n)
    })
    v.el.on('click','#minus1',()=>{
    m.data.n-=1
    v.render(m.data.n)
    })
    v.el.on('click','#mul2',()=>{
        m.data.n*=2
        v.render(m.data.n)
    })
    v.el.on('click','#divide2',()=>{
        m.data.n/=2
        v.render(m.data.n)
    })
}

上面这段代码相似度很高,并且每一段绑定的事件表达得不是很清晰,使用表驱动如下

events:{
        'click_#add1': 'add',
        'click_#minus1': 'minus',
        'click_#mul2': 'mul',
        'click_#divide2': 'div',
    },
    add() {
        m.update({n: m.data.n+1})
    },
    minus() {
        m.update({n:m.data.n -=1})
    },
    mul(){
        m.update({n:m.data.n *=2})
    },
    div() {
        m.update({n:m.data.n /=2})
    },
    autoBindEvents(){
        for(let key in c.events){
            const value = c[c.events[key]]
            const spaceIndex = key.indexOf('_');
            const part1 = key.slice(0, spaceIndex);
            console.log(part1);
            const part2 = key.slice(spaceIndex+1)
            console.log(part2);
            console.log(value);
            v.el.on(part1,part2,value)
        }
    }

这样使代码更加清晰明了了

《代码大全》对表驱动编程的描述:

表驱动方法是一种使你可以在表中查找信息,而不必用逻辑语句(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];
}

对模块化的理解

一、我是如何理解模块化的?

1、代码模块化之后无论是代码的整体性还是后期进行代码维护都变的清晰简单了起来。

2、业务模块化之后可以使业务流程更为清晰,便于开展工作,各个业务模块之间负责自己模块的业务,也避免了一些不必要的麻烦,使得工作的效率也会更高。

3、模块化我觉得是一种高效的思想,这在编程过程中提供了一种优化代码以及重构代码的方向。