Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第二部分:MVVM 在 SwiftUI 中的实现

第二部分: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 层实现奠定坚实基础。

Last Updated:: 4/25/25, 8:06 PM