mirror of
https://github.com/motajs/template.git
synced 2026-07-17 09:21:09 +08:00
10 KiB
10 KiB
必须规则
以下规则必须时刻遵守,任何情况下都不允许违反。
- 不擅自修改已有内容:将我已经写好的内容视为绝对正确。除非我明确允许,否则不允许任何修改,哪怕因为接口变化或其他原因导致其中出现类型错误。若认为我的代码存在错误,应在对话中提出,而不是直接修改。
- 不恢复我的修改:我做的任何代码修改都是有原因的。若我在两次对话期间新增、删除或修改了部分代码,不要将其恢复。
- 以目的驱动,而非以接口驱动:实现前先想清楚我为什么要这样设计接口、这个接口设计的目的是什么,而不是单纯地以将接口填满为目标。
- 遇到歧义立即提问:若思考或实现时遇到任何问题——例如描述模糊、接口不清晰、某些地方存在歧义等——应立即向我提问,而不是按自己的想法去写。
- 接口缺失时停止并提问:若完成需求所需的接口尚不存在,应立即停止实现,向我提出疑问,而不是擅自新增接口来推进。
- 按我说的方式重构:重构时不要擅自新增任何参数、方法或接口,不要仅通过新增兼容层应对重构。
- 彻底性重构(新旧接口完全没有重合):按正常方式全新实现,旧代码仅作逻辑参考。
- 结构性重构(新旧接口基本一致,细节有差距):将旧代码搬移到新接口上后进行微调。
- 不要有任何"顺手"的想法:任何时候,都不要出现顺手的想法,包括但不限于发现了一个 bug 然后顺手修复、发现一处类型错误然后顺手修复等,这种情况下应当遵循规则 1。
- 修改文件前重读文件,修改后说明内容:修改文件前务必重新阅读以确保内容是最新版。修改后必须在对话中说明所有改动的文件及具体改动内容。在修改文件时,不得修改文档的
涉及文件节未提及的文件。 - 关于
dev.md的强度升级:dev.md中"一般不建议/尽量避免"的条目在此处视为绝对禁止;"建议/最好"的条目在此处视为必须遵守。as关键字不受此升级约束。 - 参数最小化 / 级联获取:不从外部传入可通过已有引用获取的对象。若对象已持有对父对象或相关对象的引用(如
controller),应直接通过该引用获取所需数据(如controller.state),不应再单独传递参数。即"非必要不传参"。 - 转换下沉:数据的格式或类型转换(如
string的 id 转number)应放在最终消费该值的对象中完成,而非在调用方预先转换后再传入。这样可以减少调用方的职责并避免重复转换。 - 通过公有接口操作,不直接赋值内部属性:对某个对象内部状态的修改,必须通过该对象对外暴露的公有方法进行(如用
mover.face(dir).start()设置朝向并发起移动),而不是通过类型断言访问其内部属性直接赋值(如mover.faceDirection = dir)。 - map/filter 优于 for 循环:对数组进行数据收集或转换时(如收集 Promise),使用
map、filter等函数式写法,比for循环 +push的可读性更高。 - 渲染端永远处于被动:任何情况下都不可能会出现数据端主动通知渲染端进行更新的场景,渲染端仅通过钩子与数据端通信,通过钩子被动获取信息,并在某些情况下影响数据端行为。
- 按设计实现,勿自由发挥:我已想好功能的基本思路和代码结构,你的任务是还原它,而非自行创造。
- 代码首先得看着舒服:代码的第一读者是人,必须一眼就能看清整体结构,不需要反复来回读才能理顺逻辑。不出现过长的表达式,不进行不必要的函数拆分。不允许出现 3 层以上的
if嵌套。 - 关于非空判断:对于对象,直接使用
if (!object)的方式进行判断,对于字面量,使用lodash接口isNil判断if (isNil(value)),不要使用if (value === undefined)这种方式。
建议规则
以下规则为建议性,尽量遵守,特殊情况下可灵活处理。
- 参考但不盲从建议:我给出的实现建议可作为方向参考,但不应不加思考地照搬。
- 以类型标注为参考依据:实现与类型标注有冲突时,以类型标注(一般是
types.ts)中的内容为准。 - 发现接口问题时提问:若认为类型标注中的接口设计有问题,或在实现中发现缺少某些接口,应向我提问是否添加,经我同意后方可添加。
- 接口设计兼顾合理性与便捷性:设计接口时不仅要考虑合理性,还要考虑使用便捷性。罕见场景应当被支持,但不应与常见场景共用同一接口——这只会增加常见场景的使用难度。
- 避免多余的非空判断与类型守卫:类型已满足约束时不应再额外判断或过滤。例如
Promise.all接受(Promise<unknown> | void)[],无需写成Promise.all(arr.filter(v => !!v))。 - 关于整个仓库的类型检查:单个需求不需要跑全仓库的类型检查,仅在重构时需要。
开发流程
当我提出需求时,若没有明确说明直接实现或有其他明确要求,则遵循如下开发流程:
- 阅读当前代码,分析需求,将需求整理为一个 markdown 文档,放在
docs/dev目录下,注意有可能在其子文件夹下,例如docs/dev/hero,自行判断应该放到哪。文档中需明确标注需求细节,以及代码实现的大体思路。此阶段需考虑全面,遇到任何问题应向我提问并确认,不得自行假设。 - 我会对文档进行全面阅读,确认实现细节与思路无误后,方允许开始实现。我可能会对文档进行细微调整,请在实现前重新仔细阅读最终版本。实现过程中如有任何问题,应向我提问,而不是自行决定。
示例文档
对于新增接口/彻底性地重构接口,按照以下格式编写,其余需求自行组织。
- 如有需要可单独开设标题章节详述。
- 我会使用
>引用块在文档中批注,因此不要在文档中使用引用块。 - 文档控制在 100-250 行,简洁但包含所有必要信息,不擅自修改示例文档格式。
- 一般不需要流程图;若必须画,使用
mermaid。
# 需求综述
描述清楚需求的内容、动机与目的。
# 接口设计分析
这是相当重要的一章。按接口逐一分析成员与方法的预期使用频率(高/中/低,指**用户编写此调用的频率**而非运行时频率),中高频成员需列出至少一个典型使用场景。
**命名长度原则**:高频 -> 一个单词;中频 -> 不超过三个单词;低频 -> 可稍长但不宜过长。
我可能不会给完整接口设计,你需要自行分析需求补充设计,并在对话中明确指出哪些接口是你补充的。
示例如下:
## IObjectMover
### 接口综述
这里讲解接口的设计,注意不要直接写成 ts 代码,也不要简单地一个个列出,而是需要分析需求,然后经过推理自然地得出接口设计。
### 接口分析
- `IObjectMover.forward()`:预期频率**高频**。向前移动一格是地图行走、动画演出等场景的核心需求,在逻辑与演出中都会频繁出现,故为高频。典型使用场景:演出中玩家或 NPC 沿某方向连续移动。
- `IObjectMover.speed()`:预期频率**中频**。移动中修改移速有一定使用场景,但远不及 `forward`、`step` 等移动接口的频率,通常只在特殊演出或逻辑中出现,故为中频。典型使用场景:NPC 逃离怪物时先定在原地,随后逐渐加速逃跑。
- `IObjectMover.stepFace()`:预期频率**低频**。移动方向与朝向不同的常见场景(后退)已由 `backward` 覆盖,只有极特殊情况才需要此接口(如角色朝向固定但沿垂直方向平移),相当罕见,故为低频。
### 预期体量
本节应当写出预期的代码体量,并分析原因。示例如下:
预期代码体量为 200-300 行。分析如下:
- `IObjectMover` 首先需要完成计划存储与计划的定义,这些接口基本大致就是向数组中添加元素,每个方法内容都不多,整体预计在 100 行左右。
- `IObjectMover` 还需要完成移动流程的编写工作,需要根据每个移动步按照流程执行不同的行为,这一过程较为复杂,预计需要 100-200 行。
### 可能风险
若需修改已有接口(即本次新增之外的接口),在此写明修改风险(如类型污染、其他接口出错等)。只写修改已有接口的风险,不写实现风险(实现风险放到问题节)。无风险则跳过此章节。
# 实现思路
按照下面的格式分条描述实现思路。
## 1. 完成 xxx
...
## 2. 完成 xxx
...
# 涉及文件
## 需要引用的文件
按照第三方库 → 其他包 → 当前包的其他文件的顺序写。
- `xxx 库`: 引用第三方库,说明引用目的,以及需要的接口
- `@user/xxx`: 引用的目的,需要这个文件的哪些接口
- `xxx.ts`: 引用此文件的目的,需要这个文件的哪些接口
## 需要修改的文件
### `@user/package/[folder/]file.ts`
除非必要或明确提出,一般不建议擅自新增公共方法或成员,必要时可以向我提问。
- [ ] 新增 `Iinterface` 接口:描述新增接口的动机与目的,会用于干什么
- [ ] 新增 `Type` 类型别名:描述新增类型别名的动机与目的,会用于干什么
- [ ] 新增 `private readonly property` 成员:描述新增成员的动机与目的,会用于干什么
- [ ] 新增 `private method(...)` 方法:描述新增方法的动机与目的,会用于干什么
- [ ] 编写 `Class.method` 方法:描述实现的大体内容
- [ ] 修改 `Class.method` 方法中的部分内容:描述修改哪些内容,修改这些内容的目的
- [ ] 重构文件结构,将 `xxx` 与 `yyy` 修改为 `zzz` 与 `www`...
...
### `@motajs/package/[folder/]file.ts`
...
# 问题
如果描述中有歧义或比较模糊的地方,可以在此列出。
1. xxxxxx?
2. xxxxxx?