Files
iOS/逐课课纲/部门课08_项目组织与MVVM架构入门.md

121 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 部门课 08:项目组织与 MVVM 架构入门
## 教学目标
- 认识 SwiftUI App 入口、根页面、功能页面、子组件、模型、状态对象和资源分别承担什么作用。
- 理解项目组织的核心是让职责和依赖清楚,而不是建立固定数量的文件夹。
- 正式理解 MVVM 的三类职责:
- Model 保存业务数据和规则;
- View 负责显示状态并传递用户操作;
- ViewModel 管理页面需要的状态和操作,连接 Model 与 View。
- 能追踪以下数据流:
```text
用户操作
→ View 传递意图
→ ViewModel 处理操作
→ Model 或业务状态改变
→ ViewModel 发布新状态
→ View 更新
```
- 认识 `ObservableObject`、`@Published`、`@StateObject` 和 `@ObservedObject` 在本课拟采用的 MVVM 写法中的基本职责,Treversi 中的实际对应关系在备课时核对,不展开底层发布机制。
- 知道状态对象应有清楚的所有者,接收者只观察同一个对象,不随意建立重复的事实来源。
- 能初步判断一段代码更适合放在 Model、ViewModel 还是 View。
- 认识小项目可以按代码角色组织,较大项目也可以按 Game、Settings 等功能组织。
- 知道 MVVM 是一种常用选择,不是 SwiftUI 或所有 App 强制采用的唯一架构。
- 能在保持功能正常的前提下逐步拆分旧项目,并在每一步重新 Build/Run。
授课干部后续备课时可参考 Apple 的 [App organization](https://developer.apple.com/documentation/swiftui/app-organization) 和 [Managing model data in your app](https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app)。
## 教学内容
本节采用 Demo 讲解型。授课干部先运行作为课程案例的 Treversi 游戏,再从完整产品反向阅读项目结构和一次真实的数据流。课堂主要讲授:
1. 认识 `TreversiApp.swift`、资源文件、Core、Features 和 UI 等项目组成,以及 App 入口、页面、组件、模型、状态和资源之间的关系。
2. 区分“代码角色”和“目录结构”:MVVM 描述职责与依赖,Core、Features、UI 等目录描述工程中的组织方式,两者不是同一件事。
3. 从 Treversi 中寻找三类职责:
- 棋盘、玩家、配置和规则等 Model;
- 游戏状态、设置预览状态和操作处理等 ViewModel 职责;
- 棋盘、游戏、菜单和设置页面等 View。
4. 追踪一次“玩家点击合法落子位置”的完整链路:View 接收点击,状态对象处理落子意图,游戏规则和模型改变,可观察状态更新,棋盘 View 重新显示。
5. 结合源码实际写法认识:
- `ObservableObject` 表示可被观察的状态对象;
- `@Published` 标记会驱动界面变化的状态;
- `@StateObject` 用于当前 View 创建并拥有的对象;
- `@ObservedObject` 用于接收并观察外部已有对象。
6. 比较两种常见的项目组织思路:
- 小项目按 `Models / ViewModels / Views / Resources` 等代码角色分类;
- 较大项目按 Feature 分组,并保留 Core 和共享 UI。
7. 讨论何时值得拆分:某段代码已有独立职责、组件会被重复使用、页面同时混入大量显示与业务规则,或者修改功能时已经难以判断代码应该放在哪里。
8. 给出旧项目的渐进重构顺序:
- 先记录并运行原始行为;
- 标出数据、操作、规则和界面;
- 先提取 Model;
- 再建立 ViewModel 并移动状态与操作;
- 让 View 主要读取状态并传递意图;
- 最后整理文件和目录;
- 每移动一步就重新 Build/Run。
9. 简要介绍 MVC、MVI、Redux、TCA 和 Clean Architecture 的存在,只说明它们提供了不同的职责划分或状态管理方法,不比较优劣,也不要求记忆。
Treversi 只作为真实工程阅读案例。授课干部在备课阶段取得真实源码并核对 `GameState`、`PreviewBoardState` 等类型和观察关系,再确定最终课堂图示和讲解口径。
本节不讲协议抽象、依赖注入、Service、Repository、Coordinator、复杂路由、单元测试、Mock、测试驱动开发、多 Target、Swift Package 或工程模块化,也不展开 Clean Architecture、TCA 等其他架构的具体代码。不要求所有页面机械地套入 ViewModel,不以文件数量、文件夹层级或代码行数判断架构质量。
## 课后作业
作业方向为“整理我的旧作品”。具体提交目录、分支、Commit、PR 标题和截止时间以后写入独立的课后作业文档。
### 最低完成标准
- 优先选择部门课 4“小植物补水卡”或部门课 6“主题清单”;没有合适旧作品时,可以使用授课干部以后提供的备用项目。
- 重构前先确认原项目能够 Build/Run。
- 根据项目内容建立清楚的 Model、ViewModel 和 View 职责。
- 将主要职责拆入不同 Swift 文件,并使用自己能够理解的命名和目录组织。
- ViewModel 按课堂确认的 Treversi 观察方式连接 View。
- View 主要负责界面显示和传递用户意图,不继续保存主要业务规则。
- Model 不依赖具体 View。
- 重构后原有核心操作仍然正常运行。
- 完成至少一处可见修改,并能指出这项修改分别影响了哪个层次。
- 能简要追踪一次:
```text
用户操作
→ View
→ ViewModel
→ Model 或状态
→ View 更新
```
达到最低标准即可,不要求把项目改造成正式工程,也不要求目录与授课干部示例完全一致。
### 建议完成标准
鼓励根据兴趣选择一项或多项尝试:
- 将重复界面拆成独立子 View。
- 在角色分类的基础上尝试按 Feature 组织文件。
- 为 ViewModel 增加一个范围明确的新操作。
- 画一张简单的项目职责图或数据流图。
- 比较传统 `ObservableObject` 写法与现代 `@Observable` 的差异。
- 请 AI 检查某段代码是否放错职责,但由自己决定是否调整并重新运行。
建议内容不影响基础作业通过。
## 验收方式
- 学员通过个人 Fork 和作业分支向部门公开仓库提交完整项目源码 PR。
- 授课干部取得源码后确认项目能够 Build/Run,重构前后的核心行为一致。
- PR 中简要说明:
- 哪些文件属于 Model、ViewModel 和 View;
- ViewModel 拥有哪些状态和操作;
- 一次用户操作怎样经过三层并更新界面;
- 自己完成了哪一处可见修改。
- 如需证明互动效果,可以通过约定渠道发送简短运行视频,不规定视频格式和编码。
- 结合本课 PR 和作业反馈确认职责划分与操作链,不把技术抽查安排到部门课 09。
- 简短说明不完整时给予反馈,不因表达不够准确拒绝已达到基础要求的作品,也不安排逐人技术答辩、排名或淘汰。
- 未完成时允许提交 Draft PR,记录当前结构、完整错误和已经尝试的步骤。
- 不以文件数量、目录是否与授课干部完全一致、是否使用高级抽象或能否背诵其他架构作为通过门槛。
源码提交、工具故障时的参与记录和隐私边界按[共同安排](../iOS部2026十课初步规划.md)执行;具体材料与操作细节由授课干部在备课阶段准备。