核心概念
设计原则
这些工作流所强制的规则并非新造。本页先给出每条经典设计原则的标准定义,再指出项目中具体由哪条规则承载它,以及项目在哪些地方刻意附加了条件或未作规定。
如何阅读本页
下面每条原则都标有状态。有直接条款表示存在一条规则把它写成义务;附条件采纳表示只有在规定的触发条件被观察到之后才适用——项目把无条件套用视为一笔没有买家的成本;无独立条款表示项目没有为它立规矩,此时会说明原因,并给出最接近的相关约束。
面向对象设计原则
七条原则,按它们在本项目中的分量排序。
| 原则 | 标准定义 | 状态 |
|---|---|---|
SRP 单一职责原则 | 一个模块应当有且只有一个引起它变化的原因。 | 有直接条款 |
LoD 迪米特法则 | 一个单元应当尽可能少地了解其他单元的内部结构。 | 有直接条款 |
OCP 开闭原则 | 软件实体应当对扩展开放,对修改关闭。 | 附条件采纳 |
DIP 依赖倒置原则 | 高层模块不应依赖低层模块,两者都应依赖抽象。 | 附条件采纳 |
CRP 合成复用原则 | 优先使用对象组合而非类继承来实现复用。 | 附条件采纳 |
ISP 接口隔离原则 | 客户端不应被迫依赖它不使用的接口。 | 无独立条款 |
LSP 里氏替换原则 | 子类型的对象必须能替换其基类型,且不破坏程序的正确性。 | 无独立条款 |
SRP
单一职责原则
一个模块应当有且只有一个引起它变化的原因。
这是项目执行得最严格的一条。可维护性标准要求"一条规则只有一个权威归属者",而"一个不变量的归属被打散"被列为合法的设计压力信号。选择改动位置时,业务行为必须放在拥有相关数据与不变量的模块内,入口层保持轻薄;多个调用方因为下层同一条规则出错时,修复共同归属者,而不是逐个修补症状。
- CODE-02
- CODE-04
- DESIGN-04
- DOC-01
LoD
迪米特法则
一个单元应当尽可能少地了解其他单元的内部结构。
以"局部可推理"的形式存在,属于常驻规则而非某个工作流独有。维护者必须能在不心算复杂表达式、不追踪无关模块的前提下,理解控制流、状态变化、外部副作用与失败行为。同样的表述也写在设计工作流的可维护性标准里,因此它同时约束提出的边界和写下的代码。
- READ-02
- READ-03
- DESIGN-04
OCP
开闭原则
软件实体应当对扩展开放,对修改关闭。
只有在变化轴真实出现之后才采纳。"同一条真实变化轴上重复出现的条件分支"与"存在多种真实的算法或策略"被列为合法信号,后者正是策略模式成立的地方。反向要求同样明确:单实现的接口、单产品的工厂、无人修改的配置项,以及只为设想中的需求预留的扩展点,全部被逐项拒绝。在第二个实现出现之前就建好的扩展点,只是没有买家的间接层。
- DESIGN-01
- DESIGN-02
- DESIGN-03
DIP
依赖倒置原则
高层模块不应依赖低层模块,两者都应依赖抽象。
依赖方向是每份设计方案的必填内容,与边界、职责、契约、数据归属并列,因此这个问题一定会被问到。倒置本身由不稳定性触发:"不稳定的外部依赖"是被点名的设计压力,而不稳定的第三方接口正是适配器成立的既定场景;依赖隔离也是可维护性加固的对象之一。项目不要求的是:为一个稳定依赖统一加抽象层——那会落回被拒绝的预留扩展点。
- DESIGN-02
- DESIGN-03
- DESIGN-04
CRP
合成复用原则
优先使用对象组合而非类继承来实现复用。
项目不对组合与继承排序——强推统一的语言风格指南是明确的非目标,仓库自身的惯例优先。它真正立规矩的是"共享之前必须通过的判据":是否实现同一条领域规则、这条规则变化时是否所有调用方都应当一起变、被提议的归属者是否持有相关数据与不变量。仅仅长得像的代码保持各自独立。落到实践上,它与合成复用同向,因为它禁止的正是"为复用而继承"所制造的耦合。
- CODE-01
- CODE-03
- DESIGN-03
ISP
接口隔离原则
客户端不应被迫依赖它不使用的接口。
项目没有为接口粒度立条款,因为粒度属于设计方案要做的决定,而不是一条能从外部检查的规则。有两处间接触及它:"缺少稳定的公开接缝"被计为设计压力;入口层必须保持轻薄,行为归于拥有不变量的模块。因此接口形态在代码设计工作流内部决定,与其他一切一样接受同一份复杂度预算的约束。
- DESIGN-02
- CODE-04
LSP
里氏替换原则
子类型的对象必须能替换其基类型,且不破坏程序的正确性。
项目没有关于类型层次的任何规则,本页不做附会。契约一致性仍然会被检查,只是在另一个层面:评审把正确性、失败行为、兼容性作为彼此独立的审查轴;完成阶段要求每条验收行为都与新的验证结果逐条对账,而不是假定成立。一次破坏调用方的替换,会在那里以兼容性或正确性发现的形式暴露出来。
- REVIEW-01
- DONE-01
- DONE-02
复杂度预算
上面有三条原则是附条件的,原因相同:项目的既定目标是"必要的最小复杂度",既不是最少的语法,也不是最高的原则覆盖率。三个机制负责守住这一点。
没有观察到压力,就不新增抽象
压力必须能被指名:难以跟踪的控制流、隐藏的状态修改或 I/O、必须一起变化的语义重复、同一条真实变化轴上的重复条件、不稳定的外部依赖、被打散的不变量归属、真实存在的构造组合,或缺少稳定的公开接缝。
新奇税
不常见的写法、反射、元编程、隐式运行期行为、新依赖或设计模式,必须在正确性、实测性能、框架一致性或总维护成本上给出具体收益。成立时,它要被局部化在清晰的边界之后、按意图命名,并解释它为什么存在,而不是它怎么工作。
模式要计价,不计分
一个设计模式只有在"它消除的复杂度与耦合,大于它引入的接口、类、文件和间接层"时才被接受。模式的名字本身不构成质量证据。
经典原则未覆盖的约束
面向对象原则约束的是代码的形态,它们没有规定一个智能体在你的仓库周围应当如何行事——而剩下的失败模式恰恰出现在那里。
歧义在实施前解决
只有当不同答案会实质改变用户可见行为、接口、数据语义、权限、安全、兼容性、破坏性影响或验收标准时,一个问题才被允许阻塞流程。相互独立的问题合并成一批问完;可逆的内部细节从仓库推断,不拿来提问。
- REQ-01
- REQ-02
- REQ-04
批准是独立且明确的动作
检查点固定包含五项:目标、验收行为、范围外、假设、方案边界。只有在检查点之后发出的行动指令才授权实施;最初的请求、对澄清问题的回答、以及一句"已读",都不构成批准。
- REQ-03
- REQ-05
- REQ-06
证据先于结论
存在稳定的自动化接缝时,修复授权后的第一次写入必须是回归测试,并且必须先观察到它失败,才允许修改生产代码。没有新鲜且范围匹配的命令输出,不得声称完成;每条验收行为要么有证据支持,要么被明确报告为未完成。
- TEST-01
- TEST-03
- DONE-01
- DONE-02
权限不随调用而扩大
调用一个工作流不授予提交、推送、合并、发布、创建 issue、安装依赖或修改全局配置的任何权限。查看仓库状态时不打扰无关改动,也绝不回滚、覆盖或吸收不是自己做出的工作。
- SAFE-01
- SAFE-02
各项活动的归属工作流
一组精简规则在每次会话自动生效;五个工作流各自加深其中一段,这也是它们需要点名调用、而不是一起加载的原因。
| 工程活动 | 归属 | 它保证什么 |
|---|---|---|
| 需求对齐与变更控制 | 开发 | 在你批准一份写明的边界之前,不写入任何内容。 |
| 缺陷分析与回归防护 | 诊断 | 根因有证据支持;修复变绿之前,测试必须先变红。 |
| 边界与复杂度决策 | 代码设计 | 比较取舍实质不同的方案,推荐必要的最小复杂度,不写生产代码。 |
| 独立质量检查 | 评审 | 从固定比较点按八条轴检查;全程不修改仓库。 |
| 跨会话连续性 | 交接 | 八项必填内容,从仓库重新读取而非凭记忆写出。 |
| 日常纪律:复用、可读性、新鲜验证 | Engineering Core | 不需要任何命令即对每个请求生效,并刻意保持精简。 |
这份取舍是实测得出的
同一套纪律也适用于工具本身。对照实验显示:给普通任务自动加载完整工作流,工具调用与输入 token 大约多出三分之一,而结果没有变化。因此这些工作流改为用户点名调用,常驻 Core 被削减而非扩充。拿不出背后失败模式的规则不会被加入;买不到任何东西的规则会被移除。