第二部分:MVVM 在 SwiftUI 中的实现
第3章:构建 Model 层
数据模型的设计原则
在 MVVM 架构中,Model 层是应用程序的核心,负责管理数据和业务逻辑。设计良好的数据模型是构建健壮、可维护应用的基础。以下是 SwiftUI 中数据模型设计的关键原则:
1. 单一职责原则 (Single Responsibility Principle)
- 每个数据模型应仅代表一个业务实体(如
User、Product、TodoItem) - 避免将不相关的属性和方法混合在同一个模型中
- 示例:
// Good: 专注描述待办事项 struct TodoItem { let id: UUID var title: String var isCompleted: Bool } // Bad: 混杂了UI状态 struct TodoItem { let id: UUID var title: String var isCompleted: Bool var textColor: Color // UI相关属性不应属于Model }
2. 值语义优先
- 优先使用
struct而非class定义模型 - 利用 Swift 的值类型特性实现自动线程安全
- 通过
let声明不可变属性,通过var声明可变属性 - 示例:
struct UserProfile { let userId: UUID // 不可变标识符 var name: String // 可修改属性 var lastLogin: Date }
3. 可解码性设计
- 遵循
Codable协议以支持网络传输和本地持久化 - 使用与后端API一致的命名规范(可通过
CodingKeys自定义映射) - 示例:
struct TodoItem: Codable { let id: UUID var title: String var isCompleted: Bool enum CodingKeys: String, CodingKey { case id = "item_id" case title case isCompleted = "completed" } }
4. 领域驱动设计 (DDD)
- 将复杂业务逻辑封装在模型方法中
- 避免贫血模型(仅有属性没有行为)
- 示例:
struct ShoppingCart { private(set) var items: [CartItem] = [] mutating func addItem(_ product: Product, quantity: Int) { // 业务规则:相同商品合并数量 if let index = items.firstIndex(where: { $0.product.id == product.id }) { items[index].quantity += quantity } else { items.append(CartItem(product: product, quantity: quantity)) } } }
5. 可测试性设计
- 避免直接依赖全局状态或单例
- 通过协议抽象外部依赖(如网络请求、数据库访问)
- 示例:
protocol DataFetcher { func fetchTodos() async throws -> [TodoItem] } struct TodoService { let fetcher: DataFetcher func loadTodos() async throws -> [TodoItem] { try await fetcher.fetchTodos() } }
6. 类型安全设计
- 使用枚举替代魔法字符串/数字
- 利用泛型提高代码复用性
- 示例:
enum Priority: Int, Codable { case low = 1 case medium case high } struct Task { let id: UUID var title: String var priority: Priority }
验证与错误处理
- 在模型中实现数据验证逻辑
- 定义清晰的错误类型
- 示例:
struct Email { let value: String init(_ string: String) throws { guard string.contains("@") else { throw ValidationError.invalidEmail } self.value = string } } enum ValidationError: Error { case invalidEmail }
通过遵循这些原则,您可以创建出易于维护、扩展和测试的数据模型,为后续的 ViewModel 和 View 层实现奠定坚实基础。
