MVVM 和 MVC 真的要知道?

647 阅读8分钟
应评论区朋友要求,今天针对MVVM 和 MVC 的原理进行一次剖析!

image.png

事前提醒:阅读本文存在不同想法时,可以在评论中表达,但请勿使用过激的措辞。

MVVM 和 MVC 简介

MVVM(Model-View-ViewModel)和 MVC(Model-View-Controller)都是常见的软件架构模式,用于分离应用程序的用户界面、业务逻辑和数据模型。它们的目标都是使应用程序更容易开发、测试和维护。

在 MVC 模式中,视图(View)只负责显示数据,并将用户操作转发给控制器(Controller)。控制器则负责处理用户操作并更新模型(Model),最后将结果返回给视图进行显示。因此,MVC 模式中,模型和视图是相互独立的,视图和控制器也是相互独立的。

而在 MVVM 模式中,除了视图和控制器外,还引入了一个新的组件 - 视图模型(ViewModel)。视图模型充当了视图和模型之间的中介,它从模型中获取数据并将其转换为视图所需的格式,然后将数据绑定到视图上。当用户对视图进行操作时,视图模型会将用户操作转发给模型并更新视图。

相比于 MVC,MVVM 的最大优点在于数据绑定。MVVM 采用了双向绑定的方式,将视图和模型之间的数据同步处理交给框架自动完成,使代码更加简洁、易于维护。

MVVM 示例代码

下面是一个简单的 MVVM 示例代码,它实现了一个计数器应用程序。用户可以通过点击按钮来增加或减少计数器的值。

HTML 代码

<div id="app">
  <h1>计数器:{{count}}</h1>
  <button @click="increase">+</button>
  <button @click="decrease">-</button>
</div>

JavaScript 代码

// 定义 Model
const model = {
  count: 0,
  increase() {
    this.count++
  },
  decrease() {
    this.count--
  }
}

// 定义 ViewModel
const viewModel = {
  el: '#app',
  data: model,
  methods: {
    increase() {
      this.data.increase()
    },
    decrease() {
      this.data.decrease()
    }
  }
}

// 初始化 Vue 实例
new Vue(viewModel)

在这个示例中,我们使用了 Vue 框架来实现 MVVM 架构。其中,model 对象充当了数据模型,viewModel 对象充当了视图模型。视图模型中的 data 属性指向了数据模型 model,而 methods 中定义了视图模型中的方法,用于响应用户的操作。

MVC 示例代码

以下是一个简单的 MVC 示例代码,使用前端语言 JavaScript:

<!DOCTYPE html>
<html>
  <head>
    <title>Simple MVC Example</title>
  </head>
  <body>
    <div>
      <h1 id="message"></h1>
      <input id="input" type="text">
      <button id="button">Update Message</button>
    </div>

    <script>
      class Model {
        constructor(message) {
          this.message = message
        }

        getMessage() {
          return this.message
        }

        setMessage(message) {
          this.message = message
        }
      }

      class View {
        displayMessage(message) {
          document.getElementById("message").textContent = message
        }
      }

      class Controller {
        constructor(model, view) {
          this.model = model
          this.view = view

          this.updateMessage = this.updateMessage.bind(this)
        }

        updateMessage() {
          const message = document.getElementById("input").value
          this.model.setMessage(message)
          this.view.displayMessage(this.model.getMessage())
        }
      }

      const model = new Model("Hello, World!")
      const view = new View()
      const controller = new Controller(model, view)

      document.getElementById("button").addEventListener("click", controller.updateMessage)
      view.displayMessage(model.getMessage())
    </script>
  </body>
</html>

在这个例子中,我们定义了三个类:ModelViewControllerModel 表示数据模型,包含一个字符串类型的 message 属性;View 表示视图,负责将数据显示给用户;Controller 则是控制器,协调 ModelView,并在数据发生变化时更新视图。

*接下来我们就剖析一下他们俩的差异、优缺点*

MVVM 和 MVC 的差异

MVVM 和 MVC 是两种常见的前端架构模式,它们都是为了将应用程序的不同部分分离出来以提高代码的可读性、可维护性和可测试性。

MVC 架构模式

MVC 是 Model-View-Controller(模型-视图-控制器)的缩写。这种架构模式将应用程序分为三个核心组件:

  • Model 模型:负责管理数据和业务逻辑。
  • View 视图:展示数据并与用户交互。
  • Controller 控制器:协调 Model 和 View 之间的通信。

MVC 模式的核心思想是分离关注点。将数据、UI 和逻辑分开,使得每个组件更加独立,易于修改和测试。

MVVM 架构模式

MVVM 是 Model-View-ViewModel(模型-视图-视图模型)的缩写。这种架构模式基于 MVC 模式,并引入了一个新的组件:ViewModel。

  • Model 模型:负责管理数据和业务逻辑。
  • View 视图:展示数据并与用户交互。
  • ViewModel 视图模型:作为 View 和 Model 之间的粘合剂,处理和转换数据,为 View 提供简单而直接的 API。

MVVM 模式的核心思想是“数据驱动视图”。ViewModel 将 Model 中的数据转换成 View 中所需的形式。View 不需要直接访问 Model,而是通过 ViewModel 来获取和更新数据。

MVVM的优点

  • 低耦合性(Loose Coupling):MVVM模式将视图(View)和数据(Data)分离,通过ViewModel进行交互,使得视图和数据的耦合度降低,提高了应用程序的可扩展性和可维护性。

  • 可测试性(Testability):由于数据层独立出来,可以更方便地对业务逻辑进行单元测试,减少代码出错机率,提高代码质量。

  • 可重用性(Reusability):MVVM模式中,ViewModel是与视图无关的,因此可以很容易地将其重用在不同的视图中。

  • 分工明确(Separation of Concerns):MVVM模式中,每个组件的职责都非常明确,有助于开发人员进行分工合作,提高开发效率。

  • 响应式编程(Reactive Programming):MVVM模式配合使用ReactiveX等框架可以实现响应式编程,有效解决异步编程带来的问题。

MVVM的缺点

  • 学习成本较高:相比MVC和MVP,MVVM的学习曲线要更加陡峭一些,需要掌握数据绑定、命令绑定等相关知识。

  • 过多的模板代码:在MVVM模式中,为了实现数据绑定,需要编写大量的模板代码,这将增加代码的复杂度,降低代码的可读性。

  • 难以处理复杂的业务逻辑:对于一些业务逻辑比较复杂的应用程序,在MVVM模式下进行开发可能会使得代码变得更加臃肿,不太容易维护。

MVC的优点

  • 低耦合性(Loose Coupling):MVC模式将应用程序分为三个不同的部分(Model, View, Controller),并且这些部分之间的交互是通过接口完成的,使得各个组件之间的耦合度降低,提高了应用程序的可扩展性和可维护性。

  • 可测试性(Testability):由于数据层独立出来,可以更方便地对业务逻辑进行单元测试,减少代码出错机率,提高代码质量。

  • 分工明确(Separation of Concerns):MVC模式中,每个组件的职责都非常明确,有助于开发人员进行分工合作,提高开发效率。

  • 适应复杂场景:MVC模式支持复杂的用户界面和大规模的应用程序,可以很好地处理大量的数据操作和并发请求。

  • 易于维护和重构:由于代码分离,所以在修改某个部分的功能时,只需要重新编写相应的代码即可,不必担心影响其他组件。

MVC的缺点

  • 过于分散的逻辑:在MVC模式下,控制器(Controller)和视图(View)之间的逻辑比较分散,可能会造成代码维护上的困难。

  • 过于依赖控制器:在MVC模式下,所有的请求都必须经过控制器(Controller),因此控制器的负担很重,一旦出现问题,整个应用程序可能会崩溃。

  • 视图与控制器耦合度高:由于视图(View)和控制器(Controller)之间的交互比较紧密,因此代码的重用性和可移植性都不太好。

  • 类数量较多:MVC模式中需要编写两个以上的类来实现功能,所以在开发小型应用程序时,可能会显得有些冗余。

MVVM 和 MVC 在市场上的使用情况和实用性如下:

MVVM

使用情况

MVVM 是一种前端开发中较为流行的架构模式,特别是在基于现代 JavaScript 框架的应用程序(如 Angular、React、Vue.js)中广泛使用。许多大型公司和组织(如 Google、Facebook、Netflix 等)都采用了 MVVM 开发模式,以帮助他们更好地管理复杂的代码库和应对不断变化的需求。

实用性

MVVM 模式通过将视图逻辑与业务逻辑分离,并使用 ViewModel 作为桥梁来实现这种分离,从而使代码更易于维护和测试。它还可以提高代码的可重用性和可扩展性,并且使团队成员能够更好地协同工作。

另外,MVVM 也有助于减少代码中的重复性,并优化性能,因为它可以观察到数据的变化并根据需要自动更新视图。

MVC

使用情况

MVC 是一种广泛使用的后端开发框架,已经成为 Java、Ruby 和 Python 等编程语言中最受欢迎的设计模式之一。许多著名的网站,如 Twitter、GitHub 和 Shopify,也使用 MVC 模式来构建其网站后端。

实用性

MVC 模式通过将应用程序分为不同的组件(模型、视图和控制器)来实现代码的分离。这种方法使得代码更易于维护、测试和重构,并且可以提高开发速度和可靠性。

此外,MVC 模式还提供了更好的代码复用和可扩展性,因为它允许开发人员单独编辑和更新每个组件。这样一来,即使整个应用程序需要进行大量更改,也可以轻松地更新其中的某些部分,而无需重新编写整个应用程序。

综上所述,MVVM 和 MVC 都是流行的软件架构模式,具有广泛的使用情况和实用性。在选择一个合适的模式时,需要考虑项目的需求和团队的技术水平等因素。