ub-mode skill:软件工程原则

ub-mode 用于在编写或修改代码时贯彻严谨的软件工程原则。它参考了 @poteto 的部分规则(poteto-mode / pstack),将其精简,并配合确定性的质量门禁工具使用。

  1. 先让它运行起来------懒惰协议、基础思考、测试驱动开发(TDD)、从第一性原理重新设计、质疑前提、先减后加、以结果为导向的执行、打造杠杆工具,以及架构原则(领域建模、边界纪律、类型系统纪律、让操作具备幂等性、共享状态先拆分再串行化)。
  2. 再把它做好 ------修复根因、将工作组织成可验证的单元、测试行为而非实现、Crapper(CRAP < 10)、Dryer(重复相似度 < 0.8)、Mutator(覆盖未覆盖的代码、杀死存活的变异体、删除死代码),以及重构。
  3. 实践规范------记录日志、保护上下文窗口、清理工作树,以及按顺序进行小批量提交与推送。

配套工具仓库

ub-mode 依靠确定性的质量门禁工具,约束代码结构、复杂度、重复程度和测试充分性。

  • unclebob/crapper------计算每个函数的圈复杂度、测试覆盖率和 CRAP 分数,使每个函数都保持在 CRAP 阈值以下(< 10)。
  • unclebob/dryer------检测结构性代码重复,消除相似度 >= 0.8 的重复代码块。
  • unclebob/mutator------运行变异测试,暴露未覆盖的代码,以及测试未能检出的存活变异体。
  • unclebob/uml-viewer------可视化组件、覆盖率、CRAP 分数、变异测试分数和依赖方向。

技能规则(SKILL.md)

description: 编写或修改代码时遵循精简版原则。

ub-mode

每次接到变更要求,都遵循以下步骤。

  • 先让它运行起来。
  • 再把它做好。
  • 遵循实践规范。

先让它运行起来

懒惰协议
  • 同一项决策只在一个地方定义。
  • 交付能够解决问题的最小改动。
基础思考
  • 先把数据结构设计正确,再编写逻辑。
  • 优先做能帮助后续每个阶段的事情。
  • 如果另一个并发写入者会造成影响,就不要共享状态。
测试驱动开发(TDD)
  • 修改代码之前,先编写会失败的测试。
  • 确认测试因预期的原因而失败。
  • 以最小改动让测试通过。
  • 如果无法切实编写一个有效的测试,就不要写一个糟糕的测试。
从第一性原理重新设计
  • 不要把新需求硬接到旧设计上。
  • 问自己:如果这个需求一开始就存在,会怎样设计?想清楚,再分块交付。
质疑前提
  • 如果两次修复基于同一个前提,并且都未通过同一道门禁,就用一句话写出这个前提,并统计哪些参与方承载了这种不均衡。
  • 撤销这项分配。
  • 完成上述工作之前,不要开始下一次修复。
先减后加
  • 添加任何东西之前,先减少复杂度。
以结果为导向的执行
  • 以能够验证的最终状态为目标。
  • 如果事先规划过,并且能够撤销,就允许中途出现暂时失效的状态。
打造杠杆工具
  • 如果工作无法一眼看明白,就构建一个能完成它的工具。
  • 先手工完成一个单元,再让工具的结果与该单元一致。
架构
领域建模
  • 用结构表达领域,让非法状态无法出现。
  • 维护领域术语表。
  • 如果代码已经清晰且局部化,就保持原样。
边界纪律
  • 在数据进入系统的位置校验数据。
  • 在系统内部,信任这些数据。
  • 将业务逻辑保留在纯函数中。
类型系统纪律
  • 让非法值无法被表达出来。
  • 外部数据只在进入系统时解析一次。
  • 不要压制编译器的诊断。
让操作具备幂等性
  • 无论运行两次,还是在执行到一半崩溃后重新运行,最终都到达相同状态。
共享状态先拆分再串行化
  • 如果各方不需要同一个可变对象,就让各方分别拥有自己的对象。
  • 如果确实需要共享,就只允许一个写入者,并通过结构强制保证这一点。

再把它做好

修复根因
  • 复现问题。
  • 修复根因。
  • 仅仅掩盖崩溃的防护措施,算不上修复。
将工作组织成可验证的单元
  • 完成一个小单元,并验证它。
  • 然后再开始下一个。
测试行为,而非实现
  • 测试应按照使用者的方式调用代码,并检查使用者实际能看到的结果。
  • 如果所有函数都不返回任何内容时,测试仍然会通过,就丢弃这个测试。
Crapper
  • 使用 crapper 工具。
  • 通过拆分函数、补充测试或两者结合,让每个函数的 CRAP 分数低于 10。
  • 考虑是否值得减少 case 分支。
Dryer
  • 使用 dryer 工具,消除相似度达到或超过 0.8 的重复代码。
Mutator
  • 使用 mutator 工具。
  • 覆盖未覆盖的代码。
  • 杀死存活的变异体。
  • 删除死代码。
重构
  • 固定代码现有的行为。
  • 改变结构。
  • 证明行为没有发生变化。

实践规范

记录日志
  • 记录采取的每项行动及其原因。
  • 完成工作时报告这份日志。
保护上下文窗口
  • 保持主线程精简。
  • 将大块内容转移到别处,只保留摘要。
清理工作树
  • 找出可以安全删除的内容,确认仍在使用的内容不依赖它们,再回收磁盘空间。
  • 尚未提交的工作,等待作出处理决定。
提交与推送
  • 经常提交,保持提交小而有序。
  • 每次提交都说明原因、变更内容,以及如何证明变更有效。
  • 最后推送到主线。
相关推荐
Geek-Chow1 小时前
05.4 · DeepInfer 推理框架总览:源码结构、开源与未开源部分对照
人工智能
Flynn Liang1 小时前
Spring AI 多模态实战(下):文生图 + TTS 语音合成(含 2.0 流式音频分片)
人工智能·spring·文生图·音视频·语音合成·tts·springai
长不大的杨瑞杰1 小时前
OpenCode v2 Custom Tools 实战:开发数据库、工单与发布工具
人工智能·typescript·开发工具·opencode·custom tools
羊仔AI探索1 小时前
离世仅仅半个月,张雪峰被蒸馏了
人工智能·aigc·蒸馏·张雪峰·skills
Sun 32852 小时前
个人知识库建设 - 路线
ai·向量·知识库·检索·路线
zhippt_10142 小时前
只剩截图没有源文件?图转PPT把图片还原成可编辑幻灯片
前端·人工智能·powerpoint
小oo呆2 小时前
【自然语言处理与大模型】自然语言处理的漫漫长路之深度学习时代
人工智能·深度学习·自然语言处理
JavaPub-rodert2 小时前
AI Agent 的记忆系统怎么设计?从短期记忆、长期记忆到 RAG,讲透 Memory 工程化
人工智能
智恒百亿2 小时前
一台 5090 八卡服务器怎么分给一个团队用?多模型多任务的显存分配实战
java·大数据·人工智能