乐趣区

关于前端:MVVM-到底比-MVC-好在哪里

前言

MVC 和 MVVM 是比拟罕用的前端设计模式,你能分明地说出 MVVM 到底比 MVC 好在哪里吗?我最近理解了一下 SwiftUI 里的 MVVM 是怎么利用的,感觉应该记录一下本人的想法,对这两种模式的比照和优缺点做个总结。

MVC

先来回顾下 MVC 和 MVVM 各自的特色。前端的 MVC 如下所示:

三个形象角色,Model 代表模型,View 代表视图,Controller 代表控制器。三个角色间的通信如下:

  1. View 接管到用户的交互申请之后,会将申请转发给 Controller。
  2. Controller 解析用户的申请之后,就会交给对应的 Model 去解决。
  3. Model 解决完后会告诉 View。

这里要重点关注下 MVC 中数据变动是如何响应到界面上的:Model 和 View 之间应用了观察者模式,以便在 Model 变动时去响应界面的变动,也就是说 View 是依赖 Model 的。

MVVM

MVVM 中也有三个角色,Model 代表模型,View 代表视图,ViewModel 代表视图模型。通信的步骤如下:

  1. View 把用户申请传送给 ViewModel。
  2. ViewModel 告诉 Model 去解决。
  3. Model 解决完后告诉 ViewModel 须要更新。
  4. ViewModel 告诉 View 须要更新,View 从 ViewModel 中获得须要的数据。

咱们应该留神到 MVVM 跟 MVC 有一些不同:View 和 Model 没有间接的依赖关系,并且 ViewModel 会承当肯定的显示逻辑解决。

MVVM 好在哪里?

在 MVC 中,次要有两个毛病:

  1. 当 Model 发生变化时 View 会收到告诉以便获得须要的数据,这意味着 View 能够间接拜访 Model,也就是 View 耦合了 Model。那么当 Model 发生变化时,所有相干的 View 都会受到影响。
  2. 因为 Model 中不蕴含显示逻辑,所以不可避免地使 View 中会蕴含肯定的业务显示逻辑,造成 View 的职责不清和可能的代码反复。

以上的毛病在 MVVM 中都失去了改良。第一,View 只关联 ViewModel,升高了耦合性;其次,View 能够关联多个 ViewModel 来组合界面的显示,相关联 Model 的业务显示逻辑代码能够抽离到 ViewModel 中,进步了代码可重用性和灵活性,并使 View 更纯正;最初,View 和 ViewModel 通常应用双向数据绑定来简化开发者的代码编写。

MVVM 在 SwiftUI 里怎么用的

来看个 MVVM 的理论例子。SwiftUI 是通过继承和属性包装器来实现 MVVM 的利用场景的,代码写起来非常简单:

import SwiftUI

/**
 * ViewModel 层。* ViewModel 是可察看的对象,继承自 ObservableObject,观察者是 View。*/
class ViewModel: ObservableObject {
  typealias Card = MemoryGame<String>.Card
  
  static private let emojis = ["🚗", "🚕", "🚙", "🚌", "🚎", "🚝", "✈️", "🚀"]
  
  static private func createMemoryGame() -> MemoryGame<String> {MemoryGame<String>(numberOfPairsOfCards: 4) { idx in
      emojis[idx]
    }
  }
  
  /**
   * ViewModel 援用了 Model。* model 属性是 Model 层,留神有个 @Published 属性包装器。* @Published 的作用是当 model 发生变化时,ViewModel 公布告诉去告诉观察者,也就是 View。* 这里简化了 Model 告诉 ViewModel,ViewModel 再告诉 View 的过程。*/
  @Published private var model = createMemoryGame()
  
  /**
   * 以下体现的是 ViewModel 代理了对于 Model 的拜访。* 一些显示逻辑代码能够抽离到这里。*/
  var cards: Array<Card> {return model.cards}
  
  func choose(_ card: Card) {model.choose(card)
  }
}
import SwiftUI

struct EmojiMemoryGameView: View {
  /**
   * @ObservedObject 属性包装器注册了 View 和 ViewModel 的察看关系。* 当 ViewModel 发生变化时 View 会从新渲染界面。*/
  @ObservedObject var vm: EmojiMemoryGame
  
  var body: some View {// 显示的界面。}
}

总结

通过以上的形容应该能够分明地答复出 MVVM 比 MVC 到底好在哪里了。并且能够发现不同的 UI 框架在 MVVM 的应用上可能各有侧重点,比方童鞋们能够把 Vue 的 MVVM 与 SwiftUI 做个比照。

退出移动版