架构模式
MVC、MVVM、VIPER、Delegate。
35 分钟
架构模式
iOS 项目常见 MVC、MVVM、VIPER 与 Coordinator 模式。对照 /roadmaps/ios「Architecture」节点:选对架构让 View 薄、业务可测、依赖可替换。
学习目标
- 理解 UIKit MVC 的 Massive ViewController 问题
- 用 MVVM + Combine/async 分离 View 与业务逻辑
- 了解 Delegate、Coordinator 解耦导航
- 对照 Spring 分层与 React 组件架构
核心概念
MVC 与 MVVM
UIKit 默认 MVC:ViewController 往往承担过多职责(网络、布局、导航),俗称 Massive ViewController。
MVVM 将 UI 状态与业务分离:
import Foundation
import Combine
// Model
struct Track: Identifiable, Codable {
let id: Int
var title: String
var lessonCount: Int
}
// ViewModel
@MainActor
final class TrackListViewModel: ObservableObject {
@Published var tracks: [Track] = []
@Published var isLoading = false
@Published var errorMessage: String?
private let repository: TrackRepository
init(repository: TrackRepository = TrackRepository()) {
self.repository = repository
}
func loadTracks() async {
isLoading = true
errorMessage = nil
do {
tracks = try await repository.fetchAll()
} catch {
errorMessage = error.localizedDescription
}
isLoading = false
}
}
// Repository(数据层,类似 Spring Repository)
protocol TrackRepositoryProtocol {
func fetchAll() async throws -> [Track]
}
final class TrackRepository: TrackRepositoryProtocol {
func fetchAll() async throws -> [Track] {
// URLSession 或 Core Data 实现
try await Task.sleep(nanoseconds: 500_000_000)
return [
Track(id: 1, title: "iOS 入门", lessonCount: 12),
Track(id: 2, title: "Spring Boot", lessonCount: 20),
]
}
}
SwiftUI View 只订阅 ViewModel 的 @Published 属性,类似 React 组件订阅 Hook 返回的状态。
Delegate 模式
protocol LessonSelectionDelegate: AnyObject {
func didSelectLesson(_ lesson: Lesson)
}
class LessonListViewController: UIViewController {
weak var delegate: LessonSelectionDelegate?
}
Delegate 是 iOS 经典解耦方式:UITableViewDelegate、URLSessionDelegate 等均基于此。weak 避免循环引用。
Coordinator 导航
Coordinator 接管 ViewController 间的 push / present 逻辑,ViewController 不再互相引用,便于单元测试与模块化。