modular-design
模块化拆分与模块间通信的决策技能。在进行架构设计、模块划分、文件结构规划时激活,确保拆分合理、依赖清晰。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
模块化拆分与模块间通信的决策技能。在进行架构设计、模块划分、文件结构规划时激活,确保拆分合理、依赖清晰。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
GitHub Release 发布操作规范。在需要发布版本、上传安装包到 GitHub Release 时激活,确保使用正确的命令和流程。
确认/删除等交互弹框统一使用 showTolyPopPicker 底部弹出样式。在需要弹出确认框、删除确认、操作选择时激活,确保交互风格一致。
后端服务启动与数据库操作规范。在需要启动后端服务、运行 API 测试、执行数据库迁移或遇到连接错误时激活,确保使用正确的命令和流程。
功能归档规范。在归档功能版本、更新功能网、创建存档快照时激活,确保节点编号正确、网络图完整。
使用 tolyui_mediax 实现媒体预览。适用于图片九宫格展示、全屏预览、手势缩放、视频播放、Hero 动画等场景。
Flutter Widget/Page 组件代码评审技能。在需要审查组件代码质量、发现设计问题时激活,确保输出结构化的问题清单和改进建议。
| name | modular-design |
| description | 模块化拆分与模块间通信的决策技能。在进行架构设计、模块划分、文件结构规划时激活,确保拆分合理、依赖清晰。 |
| metadata | {"model":"manual","last_modified":"Mon, 12 May 2026 00:00:00 GMT"} |
问:这段代码应该留在当前模块,还是拆出去?
判断流程:
1. 能用一句话说清楚当前模块的职责吗?
→ 能 → 不拆
→ 需要用"和"连接两件事 → 考虑拆
2. 这两块代码的变更理由相同吗?
→ 相同(都是因为"聊天功能变了"才改)→ 不拆,内部分目录就够
→ 不同(一个因为"认证流程变了",一个因为"用户资料变了")→ 拆
3. 拆完之后两个模块之间会大量来回调用吗?
→ 会 → 不该拆,它们本来就是一个东西
→ 不会 → 拆
核心原则:按业务域拆,不按技术层。一个业务模块内部包含 data/logic/view 是正常的,不要拆成 chat_network + chat_cache + chat_ui 三个独立包。
问:用目录分区够了,还是需要独立 package/crate?
判断流程:
1. 模块边界稳定了吗?
→ 还在探索阶段,边界可能变 → 逻辑隔离(目录分区)
→ 边界已经清晰稳定 → 考虑物理隔离
2. 有没有出现"不小心 import 了不该 import 的东西"?
→ 没有 → 逻辑隔离够用
→ 有,而且靠 code review 拦不住 → 物理隔离
3. 这个模块需要被多个项目复用吗?
→ 是 → 物理隔离
→ 否 → 看前两条
物理隔离后:barrel file(入口文件)就是模块的公开 API。没导出的,对外界就是不存在的。内部随便重构,只要 barrel file 不变,外界无感。
问:A 模块需要和 B 模块交换信息,用什么方式?
优先级(从简单到复杂):
1. 直接调用 → A import B 的公开 API,直接调方法
适用:A 依赖 B,方向清晰,B 的接口稳定
2. 回调/闭包 → A 把函数注入 B,B 在合适时机调用
适用:B 需要 A 的信息但不能依赖 A(如底层需要高层的 Token)
3. Stream/事件 → B 广播事件,A 订阅监听
适用:一对多通知,发布方不关心谁在听
4. 组装层中转 → A 和 B 互不依赖,由 main.dart 把 A 的输出接到 B 的输入
适用:两个平级业务域完全独立
选择原则:能用 1 解决的别用 2,能用 2 解决的别用 3。
问:这个依赖关系安全吗?
规则:
- 短命依赖长命 → 安全(聊天页依赖 WsClient ✓)
- 长命依赖短命 → 危险(WsClient 持有聊天页引用 ✗)
- 上层依赖下层 → 正常(View → Cubit → Repository ✓)
- 下层依赖上层 → 违规(Repository import View ✗)
- 平级互相依赖 → 循环依赖,需要重构
长命通知短命的正确方式:Stream/事件。短命的订阅,用完取消,互不牵连。
问:这个类/组件应该放到 shared 模块吗?
判断流程:
1. 它被几个模块使用?
→ 只有一个 → 留在那个模块里
→ 两个及以上 → 考虑放 shared
2. 它和业务逻辑有关吗?
→ 有(如 Conversation 模型)→ 放到对应的业务模块,让其他模块依赖它
→ 没有(如 AvatarWidget、SearchBar)→ 放 shared
3. shared 模块是不是越来越大了?
→ 是 → 审视一下,有没有只被一个模块用的东西混进来了
改了底层模块的类,上层所有引用该类的模块都可能需要同步更新。
问:一个新功能应该加到现有模块里,还是独立出去?
判断流程:
1. 现有模块是否已经稳定(很少变更)?
→ 是 → 继续判断
→ 否(本身也在频繁变更)→ 加进去,一起迭代
2. 新功能是否可能频繁变更、反复调整?
→ 是 → 独立出去,不要让不稳定的部分拖累稳定的模块
→ 否(一次性做完就不动了)→ 加进去
3. 新功能的变更是否会导致现有模块的消费方被迫跟着改?
→ 会 → 必须独立,否则每次调整都是连锁反应
→ 不会(内部变更,公开 API 不变)→ 可以加进去
核心原则:稳定的模块是系统的地基,不要往地基里塞实验性的东西。把不确定的、可能反复调整的功能隔离到独立模块,让它自己折腾,不影响已经稳定运行的部分。
问:这段代码将来可能被其他模块/项目复用吗?
判断流程:
1. 它是否和具体业务逻辑无关(纯工具、纯 UI 组件、纯算法)?
→ 是 → 适合独立成可复用模块
→ 否 → 留在业务模块内部
2. 它的接口是否足够通用(不依赖特定的业务类型)?
→ 是 → 可以抽出来
→ 否(参数里有业务模型)→ 先留着,等第二个消费方出现再抽
3. 现在就有多个消费方吗?
→ 是 → 抽出来
→ 否(只是"将来可能")→ 不要过早抽象,等真正需要时再动
核心原则:不要为了"将来可能复用"就提前抽象。过早抽象的代价是:接口设计基于猜测而非真实需求,等真正的第二个消费方出现时,往往发现接口不对,还得重来。等到第二个消费方真的出现了,再抽也不迟。