《JavaScript进阶--浅析 MVC》

1. 什么是 MVC

定义:

MVC(Model-View-Controller)是最常见的软件架构之一,当然也可以称之为广义的设计模式,业界有着广泛应用,为什么要使用 MVC 呢?因为复杂的软件必须有清晰合理的架构,否则无法开发和维护

MVC 是 Model-View-Controller 三个单词的简称,这也表明 MVC 是由三个部分组成的,每个部分都有不同的职责

  • Model 是负责组织数据的,里面封装了处理数据的业务逻辑。
  • View 是负责展示结果渲染页面的。
  • Controller 属于中间层,可以理解为 Model 和 View 的一个纽带,Model 和 View 是通过 Controller 来交互的,这样可以解耦,增加系统的灵活性。

注:MVC 并不是很严格的定义,所以在具体实现的时候根据理解不同会有不同的表现形式,例如也有 Model 直接渲染页面,而没有通过 Controller 的,如果是这种方式其实可以将 View 和 Controller 合并处理。

关系如图

View
Controller
Model

业务逻辑如下:

用户点击页面 View – > 调用 Controller 中的函数 --> Controller 调用 Model 中的函数执行业务逻辑 --> Controller 监听 Model 数据变化,根据相应业务逻辑重新渲染页面 View。

伪代码如下:

首先定义 Model、Controller 、View 三个类,并封装好对应的业务逻辑,最后通过页面绑定的事件触发业务逻辑的执行。

//Model 类
class Model {
    constructor(param) {
        this.param = param
    }

    getData() {
        //执行业务逻辑并返回数据
        return $.ajax(`https://xxx.com?param=${this.param}`)
    }
}
// 定义 Controller 类
class Controller {
    constructor(url, param) {
        this.url = url
        this.param = param
    }

    getDataAndRender() {
        // 先从  Model 拿到待渲染数据
        let model = new Model(this.param)
        // 将数据传入到 View 中
        let view = new View(model.getData())
        // 重新渲染页面
        view.render()
    }
}

class View {
    constructor(data) {
        this.data = data
    }

    render() {
        // 根据数据渲染页面
        let html = createHtml(this.data)
        // 将新的 html 渲染页面
        documentAppendHtml(html)
    }
}

// 监听点击事件,并执行业务逻辑
html.addEventListener('click', () => {
    let url = getHtmlUrl()
    let param = getHtmlParam()
    let c = new Controller(url,param)
    c.getDataAndRender()
})

2. EventBus

EventBus 主要功能就是可以让我们更灵活的监听事件。之所以在 MVC 的文章中介绍 EvenBus 是因为我们经常在Controller 用 EventBus 来监听 Model 中的数据状态,如果状态有变化就执行相应的渲染操作。

伪代码如下:

// 使用jQuery库创建了一个eventbus。
const $eventbus=$({}); 

class Model {
    constructor(param) {
        this.param = param
    }

    getData() {
        this.data = $.ajax(`https://xxx.com?param=${this.param}`)
        // 注册自定义事件
        $evenBus.trigger("model.update.data", this.data)
        return this.data
    }
}

class Controller {
    constructor(url, param) {
        this.url = url
        this.param = param
    }

    getDataAndRender() {
        // 监听 evenBus 自定义事件,当数据变化后就可以直接拿到数据
        $evenBus.on('model.update.data', (data) => {
            let view = new View(data)
            view.render()
        })
    }
}

3. 表驱动编程

定义

表驱动法就是一种编程模式,从表里面查找信息而不使用逻辑语句。事实上,凡是能通过逻辑语句来选择的事物,都可以通过查表来选择。对简单的情况而言,使用逻辑语句更为容易和直白。但随着逻辑链的越来越复杂,查表法也就愈发显得更具吸引力。

为什么用表驱动编程

在我们平时的开发中,if else是最常用的条件判断语句。在一些简单的场景下,if else用起来很爽,但是在稍微复杂一点儿的逻辑中,大量的if else就会让别人看的一脸蒙逼。
如果别人要修改或者新增一个条件,那就要在这个上面继续增加条件。这样恶性循环下去,原本只有几个if else最后就有可能变成十几个,甚至几十个,这样会导致代码的可维护性很差。

下面举一个很经典的关于日期的查询逻辑:

伪代码如下:

使用if else:

function iGetMonthDays(iMonth) {
  let iDays;
  if(1 == iMonth) {iDays = 31;}
  else if(2 == iMonth) {iDays = 28;}
  else if(3 == iMonth) {iDays = 31;}
  else if(4 == iMonth) {iDays = 30;}
  else if(5 == iMonth) {iDays = 31;}
  else if(6 == iMonth) {iDays = 30;}
  else if(7 == iMonth) {iDays = 31;}
  else if(8 == iMonth) {iDays = 31;}
  else if(9 == iMonth) {iDays = 30;}
  else if(10 == iMonth) {iDays = 31;}
  else if(11 == iMonth) {iDays = 30;}
  else if(12 == iMonth) {iDays = 31;}
  return iDays;
}

使用表驱动:

const monthDays = [
  [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
  [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
]
function getMonthDays(month, year) {
  let isLeapYear = (year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0) ? 1 : 0
  return monthDays[isLeapYear][(month - 1)];
}
console.log(getMonthDays(2, 2000))

ps: 定义中的表指的数数据结构,根据场景不同可以是任意的数据结构,只要能解决问题就行,例如哈希表,数据,等数据结构在一定情况下都可以作为表来使用。

4. 模块化

我理解的模块化就是一种代码的管理模式,在一个大型项目中我们经常会将耦合性非常强的功能的代码都放在一起,当使用的时候只是简单的配置就能够复用,这极大地提高了代码的灵活性、复用性、和可维护性。

模块化的理念是起源于服务端的,因为刚开始所有的业务逻辑都在服务端,所以后端工程师在维护项目代码的时候遇到了极大地挑战,经过不断的抽象和总结最终总结出了这个理念。

当前端的需求越来越复杂的时候当然顺理成章的进行代码模块化的改进了。

而前端比较出名的框架都是基于模块化的理念创建的。

所以理解和熟练的使用模块化管理代码是一个工程师必经之路。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值