| name | xxf-aaa-class-declaration-guidelines |
| description | 规范 ViewController 与 ViewModel 的分区组织方式。用于治理成员变量和方法过多、顺序混乱、阅读成本高的问题;通过 MARK 分区和职责分层保持代码导航清晰。 |
| allowed-tools | Read, Glob, Grep, Edit, Write |
VC/VM 分区治理(ViewController and ViewModel Partition)
触发场景
- 一个 VC 或 ViewModel 成员变量很多,阅读时找不到重点
- 方法越来越多,初始化、事件、业务逻辑混在一起
- 同一文件里的属性和方法顺序混乱,review 成本高
- 需要统一 VC/VM 的 MARK 分区结构
核心目标
让 VC/VM 在大纲中可快速导航:
- 变量按职责分区,不按“写代码顺手顺序”堆放。
- 方法按业务职责分区,初始化、绑定、事件、数据、渲染分离。
- 分区命名稳定,跨页面结构一致。
- 每个声明(字段和方法)都有注释,读代码时无需反向猜测用途。
Swift 文件头注释规则(强制)
适用范围:新建或重命名的 VC/VM 主文件与职责 extension 文件(如 XxxViewController.swift、XxxViewModel.swift、XxxViewController+UI.swift)。
- 禁止提交仍含占位词的头注释:
文件名.swift、项目名、git用户名、年/月/日、作用(一句话介绍)。
作用必须一句话写清该文件唯一职责,禁止空泛描述(如“处理逻辑”“相关代码”)。
自动推断与填充规则(vibecoding)
生成 Swift 文件时按以下顺序自动填充:
文件名.swift:使用当前真实文件名,并保持与主类型名一致(遵循 xxf-aaa-coding-style)。
项目名:优先使用当前 target/module 名;无法确定时回退为仓库目录名 xxf_ios。
git用户名:优先 git config user.name;为空时回退 git config user.email 的本地部分;仍为空则使用系统用户名。
年/月/日:使用当前本地日期,格式固定为 yyyy/MM/dd(示例:2026/05/21)。
作用(一句话介绍):根据主类型与文件职责自动推断并填充,不可留空。
- 若上下文不足以精确命名场景,至少基于类型名生成可读职责描述,禁止保留模板占位文案。
建议推断模板:
*ViewController.swift:负责 <页面/场景> 的展示、交互与生命周期编排。
*ViewModel.swift:负责 <页面/场景> 的状态管理、输入处理与数据编排。
+UI.swift:扩展 <主类型> 的 UI 搭建与布局职责。
+Bind.swift:扩展 <主类型> 的状态绑定与事件绑定职责。
+Event.swift:扩展 <主类型> 的事件处理职责。
+Data.swift:扩展 <主类型> 的数据请求与数据组装职责。
+Actions.swift:扩展 <主类型> 的交互响应职责。
声明注释规则(强制)
- 每个字段都要有注释,说明“存的是什么、给谁用、何时变化”。
- 每个方法都要有注释,说明“做什么、输入输出、关键副作用”。
- 优先使用
/// 文档注释,不要只写无信息注释(如“按钮点击”)。
示例:
var pageIndex: Int = 1
var hasMore = true
func loadNextPage() { ... }
VC 变量分区规则(强制)
至少按以下类别分区:
- 页面入参(从外部页面或路由传入)
- UI 组件(按钮、列表、容器等)
- 业务状态(状态机、计数、选中态、缓存态)
- 依赖对象(ViewModel、Service、Repository、Coordinator)
示例:
final class OrderDetailViewController: UIViewController {
var orderID: String
var source: OrderSource
private lazy var titleLabel = UILabel()
private lazy var payButton = UIButton(type: .system)
private lazy var tableView = UITableView()
private var state: ViewState = .idle
private var selectedCouponCount = 0
private let viewModel: OrderDetailViewModel
}
方法分区规则(强制)
至少按以下类别分区:
- Lifecycle
- Setup UI
- Bind / Event
- Data / Request
- Render / State Apply
- Action Handler
- Private Helper
示例:
override func viewDidLoad() { ... }
private func setupUI() { ... }
private func setupLayout() { ... }
private func bindViewModel() { ... }
private func bindActions() { ... }
private func fetchData() { ... }
private func render(_ state: ViewState) { ... }
@objc private func payButtonTapped() { ... }
private func makePriceText() -> NSAttributedString { ... }
ViewModel 变量分区规则(强制)
至少按以下类别分区:
- Input(外部输入、路由参数、初始化参数)
- Output State(可观察状态流,如
Obs / Flow / Driver)
- Business State(分页、筛选、缓存标志、加载状态)
- Dependencies(Repository、Service、UseCase)
示例(对应你给的场景):
final class OrderListViewModel {
var keyword: String
var source: EntrySource
var stateA: Obs<String>
var stateB: Obs<String>
var pageIndex: Int = 1
var hasMore = true
private let repository: OrderRepository
}
ViewModel 方法分区规则(强制)
至少按以下类别分区:
- Lifecycle / Setup
- Input Handling(处理 Action/Intent)
- Data Request(请求与分页)
- State Mutation / Reduce(更新状态)
- Output / Notify(向外发出状态或事件)
- Private Helper
示例:
func setup() { ... }
func didTapRefresh() { ... }
func didChangeKeyword(_ keyword: String) { ... }
func loadFirstPage() { ... }
func loadNextPage() { ... }
private func applyPageResult(_ result: PageResult) { ... }
private func emitError(_ error: Error) { ... }
private func buildQuery() -> Query { ... }
扩展分区规则
当方法增长后,优先按 extension 职责拆分到独立文件:
XxxViewController+UI.swift
XxxViewController+Bind.swift
XxxViewController+Event.swift
XxxViewController+Actions.swift
XxxViewController+Data.swift
同一 extension 文件内部仍需 MARK 分区,避免“拆了文件但文件内部继续混乱”。
治理动作
当命中触发场景时,本 skill 的默认动作:
- 若涉及新建/重命名 Swift 文件,先生成并补全标准文件头注释(含自动推断字段)。
- 识别当前 VC/VM 的属性和方法职责。
- 在不改变业务行为前提下重排顺序并补 MARK。
- 为缺失注释的字段和方法补齐用途说明与关键副作用说明。
- 合并重复或语义重叠的分区名(如 UIInit/UISetup 统一为 Setup UI)。
- 若单文件持续膨胀,提出 extension 拆分并执行最小可行拆分。
命名建议
- 分区名用稳定词汇,避免同义词乱用:
- VC 维度:
Input、UI、State、Dependencies
- VM 维度:
Input、Output State、Business State、Dependencies
- 方法维度:
Lifecycle、Setup UI、Bind、Data、Render、Actions、Helpers
- 不要使用无信息分区名,如
Other、Temp、Misc。
与其他 skill 的关系
- 代码总流程由
xxf-aaa-delivery-loop 编排
- 通用风格规则由
xxf-aaa-coding-style 约束
- 架构边界问题由
xxf-aaa-coding-arch / xxf-aaa-architecture-review 处理
- ViewModel 基础用法由
xxf-viewmodel 约束
非目标
- 不做业务逻辑重写
- 不为了分区而引入大规模重构
- 不改变公开 API 或页面行为