MVVM 模式
分离视图、视图模型和模型的职责。
MVVM 模式 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
什么是 MVVM
MVVM 代表模型-视图-视图模型。它是一种架构模式,将应用分为三个层次,每个层次都有清晰且单一的职责。
- 模型 — 数据和业务规则
- 视图 — 用户看到的内容
- 视图模型 — 为视图准备模型数据的桥梁
其目标是分离关注点:每个层次都因自身原因而变化,不受其他层次影响。
模型层
模型保存原始数据以及管理这些数据的规则。它不了解屏幕,也不了解内容如何显示。
模型通常是普通结构体或领域对象。由于不依赖用户界面,它们很容易测试。
struct User {
let id: UUID
let firstName: String
let lastName: String
let isPremium: Bool
}
struct Order {
let items: [String]
let total: Decimal
}视图层
视图只负责呈现。在 SwiftUI 中,它是您的 View 结构体;在 UIKit 中,它是您的 UIViewController 及其子视图。
优秀的视图不包含业务逻辑。它只负责渲染状态,并将用户操作转发给视图模型。
struct ProfileView: View {
@StateObject var viewModel: ProfileViewModel
var body: some View {
VStack {
Text(viewModel.displayName)
if viewModel.showBadge {
Text("Premium")
}
}
}
}视图模型层
视图模型位于模型和视图之间。它接收模型的原始数据,并将其转换为视图可以直接显示的适合呈现的值。
它还会公开用户意图对应的方法,供视图在用户交互时调用。
final class ProfileViewModel: ObservableObject {
@Published var displayName: String
@Published var showBadge: Bool
init(user: User) {
displayName = user.firstName + " " + user.lastName
showBadge = user.isPremium
}
}为什么要分离关注点
当格式化、网络请求和渲染全部纠缠在一个视图控制器中时,该文件就会变成一个庞大且无法测试的代码团。
通过拆分职责:
- 模型可以在多个屏幕之间复用
- 视图模型可以脱离用户界面进行单元测试
- 视图保持小巧且声明式
模型中应包含什么
模型中应放置:
- 领域实体(
User、Product) - 业务验证规则
- 持久化和网络抽象(通常通过视图模型调用的服务实现)
绝不要将用户界面字符串、颜色或格式化逻辑放入模型。
视图模型中应包含什么
视图模型负责呈现逻辑:
- 将日期、货币和姓名格式化为显示字符串
- 决定哪些用户界面状态可见(加载中、错误、空状态)
- 协调对服务的调用并公开结果
final class CartViewModel: ObservableObject {
@Published var totalText: String = ""
func update(with order: Order) {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
totalText = formatter.string(from: order.total as NSNumber) ?? "-"
}
}视图中应包含什么
视图只能:
- 排列并渲染用户界面元素
- 读取视图模型发布的状态
- 通过调用视图模型的方法转发点击和手势
如果您在视图中发现用于决定业务规则的 if,那么这段逻辑很可能应该放在视图模型中。
MVVM 中的数据流
数据沿一个方向流动,操作则沿相反方向流动:
- 数据流:模型 -> 视图模型 -> 视图
- 用户意图流:视图 -> 视图模型
视图永远不会直接与模型通信。这样可以让依赖朝向领域内部。
MVVM 与 MVC
在经典的MVC中,控制器通常会变得非常庞大,因为它同时负责格式化、网络请求和视图连接。
MVVM 将这些呈现逻辑提取到视图模型中,使控制器(或 SwiftUI 视图)保持轻量。视图模型与用户界面框架无关,因此更容易测试。
一个完整的切片
下面是一个将各层连接起来的小型但完整的 MVVM 切片。
struct Account { let balance: Decimal }
final class AccountViewModel: ObservableObject {
@Published var balanceText: String
init(account: Account) {
balanceText = "$" + "\(account.balance)"
}
}
struct AccountView: View {
@StateObject var viewModel: AccountViewModel
var body: some View { Text(viewModel.balanceText) }
}快速检查
测试您对 MVVM 各层职责的理解。
回顾
您已经学习了MVVM的三个层次及其边界:
- 模型 — 原始数据和业务规则,不包含用户界面
- 视图模型 — 呈现逻辑和用户意图
- 视图 — 纯粹渲染视图模型的状态
保持这些关注点分离,可以让您的代码易于测试、复用和理解。接下来,我们将通过绑定把视图模型连接到视图。
常见问题解答
「MVVM 模式」课时是免费的吗?
是的 — 「MVVM 模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「MVVM 模式」这节课中我会学到什么?
分离视图、视图模型和模型的职责。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「MVVM 模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- MVVM 模式
- 将视图模型绑定到视图
- 协调器模式
- 测试视图模型