前言
MVC 和 MVVM 是比拟罕用的前端设计模式,你能分明地说出 MVVM 到底比 MVC 好在哪里吗?我最近理解了一下 SwiftUI 里的 MVVM 是怎么利用的,感觉应该记录一下本人的想法,对这两种模式的比照和优缺点做个总结。
MVC
先来回顾下 MVC 和 MVVM 各自的特色。前端的 MVC 如下所示:
三个形象角色,Model 代表模型,View 代表视图,Controller 代表控制器。三个角色间的通信如下:
- View 接管到用户的交互申请之后,会将申请转发给 Controller。
- Controller 解析用户的申请之后,就会交给对应的 Model 去解决。
- Model 解决完后会告诉 View。
这里要重点关注下 MVC 中数据变动是如何响应到界面上的:Model 和 View 之间应用了观察者模式,以便在 Model 变动时去响应界面的变动,也就是说 View 是依赖 Model 的。
MVVM
MVVM 中也有三个角色,Model 代表模型,View 代表视图,ViewModel 代表视图模型。通信的步骤如下:
- View 把用户申请传送给 ViewModel。
- ViewModel 告诉 Model 去解决。
- Model 解决完后告诉 ViewModel 须要更新。
- ViewModel 告诉 View 须要更新,View 从 ViewModel 中获得须要的数据。
咱们应该留神到 MVVM 跟 MVC 有一些不同:View 和 Model 没有间接的依赖关系,并且 ViewModel 会承当肯定的显示逻辑解决。
MVVM 好在哪里?
在 MVC 中,次要有两个毛病:
- 当 Model 发生变化时 View 会收到告诉以便获得须要的数据,这意味着 View 能够间接拜访 Model,也就是 View 耦合了 Model。那么当 Model 发生变化时,所有相干的 View 都会受到影响。
- 因为 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 做个比照。