关于 programming-principles
将 14 本软件工程书籍中的原则用于实现、代码审查、重构和设计的技能。它按任务类型关联书籍,并提供结构化的代码评估流程。
主要功能
- 01按任务映射书籍原则
- 02代码审查与实现指导
- 03重构和架构原则
- 04结构化代码评估流程
- 05按书籍分类的参考文件
适用场景
- 01依据相关工程原则审查代码
- 02规划保持行为不变的重构
- 03评估架构与依赖边界
- 04评估遗留代码中的高风险变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ magnus919/ agent-skills --skill programming-principles安装后在 Claude Code 中输入/programming-principles确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdevals/evals.jsonreferences/a-philosophy-of-software-design.full.mda-philosophy-of-software-design.mini.mdclean-architecture.full.mdclean-architecture.mini.mdclean-code.full.mdclean-code.mini.mdcode-assessment-workflow.mdcode-complete.full.mdcode-complete.mini.mddesigning-data-intensive-apps.full.mddesigning-data-intensive-apps.mini.mddomain-driven-design-distilled.full.mddomain-driven-design-distilled.mini.mddomain-driven-design.full.mddomain-driven-design.mini.mdimplementing-domain-driven-design.full.mdimplementing-domain-driven-design.mini.mdpatterns-of-eaa.full.mdpatterns-of-eaa.mini.mdrefactoring-guru.full-smells-and-priorities.mdrefactoring-guru.full-technique-playbook-and-safety.mdrefactoring-guru.full.mdrefactoring-guru.mini.mdrefactoring.full.mdrefactoring.mini.mdrelease-it.full.mdrelease-it.mini.mdthe-pragmatic-programmer.full.md详细介绍
编程原则(14 本书)
这些原则提炼自 mattpocock/agent-rules-books 仓库——其中包含 14 套预先编写的 AGENTS.md 规则集,源自经典软件工程书籍。在代码审查、重构、设计和实现过程中,可直接运用这套技能。
如需深入了解某本书的内容,请加载相应的参考文件。
任务与书籍映射
任务涉及…… 加载/应用以下原则 ──────────────────────────────────────────────────────────────────────── 日常实现与代码审查 Clean Code、Code Complete 重构现有代码 Refactoring、WELC 架构/依赖管理 Clean Architecture、APoSD 领域建模/业务规则 DDD、DDD Distilled、IDDD 企业应用模式/分层 PoEAA 生产可靠性/稳定性 Release It! 数据一致性/可扩展性/事件 DDIA 工程实践/自动化 Pragmatic Programmer API/模块边界设计 APoSD 遗留代码/高风险变更 WELC、Refactoring
如何进行代码评估
如需结合书籍原则与实际仓库探索,进行结构化、可复现的工作流,请参阅 references/code-assessment-workflow.md。其中涵盖:加载评估框架、阅读仓库与 GitHub 上下文、排查与现有 issue/PR 的重复项、按书籍与优先级分类发现的问题,以及判断每项问题是否值得创建 issue。
跨领域原则
综合多本书的原则,按关注点整理如下。
命名与沟通
- 在整个代码库中,同一概念只用一个术语。重命名属于设计工作。
- 名称应揭示抽象,而非机制。优先使用领域术语,而非技术实现细节。
- 函数使用动词,类/类型使用名词,布尔值使用谓词。
- 如果一个名称需要注释来解释,那它就是错误的名称。
- 注释用于说明理由、契约、警告和不明显的约束——绝不用于叙述代码或弥补糟糕的命名。
函数与例程
- 每个函数只包含一个抽象层次。自上而下讲清楚整个过程。
- 参数要少。出现布尔标志就意味着应拆分函数。
- 将命令(修改状态)与查询(返回答案)分开。绝不能兼而有之。
- 当模块超过约 400 行,或需要滚动才能理解其完整范围时,就应考虑拆分。按稳定的职责边界拆分,而非按执行顺序或框架惯例拆分。
- 主流程必须清晰易读。将错误处理、边缘情况和清理逻辑与主流程隔离。
- 如果一个函数长到无法准确命名,那它就太长了。提取子函数。
架构与边界
- 源代码依赖应向内指向更高层策略。领域层和用例层绝不导入框架、数据库、UI 或供应商 SDK。
- 每个外部依赖——HTTP 客户端、文件系统、数据库、供应商 SDK——都必须位于由内层拥有的 trait 或接口之后。在应用逻辑或领域逻辑中直接实例化基础设施代码,属于结构性违规(依赖倒置原则)。
- 框架、数据库、交付机制和设备都是外层细节。应将它们置于端口、网关和适配器之后。
- 优先按业务能力/用例组织,而非按技术层组织(controllers/、services/、repositories/)。
- 依赖规则:内层拥有所需接口;外层负责实现这些接口。
- 应根据易变性和策略重要性选择边界,而非依据规模或习惯。
- 包装器、层或抽象必须隐藏比其引入的更多复杂性。仅做透传的层会成为技术债。
数据与状态
- 优先选择能让无效状态无法表示的类型。对封闭集合使用枚举,对有意义的基本类型使用值对象,仅在表示二元含义时使用布尔值。
- 明确数据所有权:区分事实来源与派生数据、缓存数据或临时数据。
- 将共享可变状态、全局变量和环境上下文视为必须证明其价值的成本。
- 清晰呈现身份、生命周期、变更和加载行为。
- 每条系统知识只保留一种权威表示。其他内容一律派生或生成。
测试
- 测试是生产代码:可读、确定,并与行为一致。
- 测试应聚焦外部可见行为,而非内部实现细节。
- 修改未经测试代码的行为前,先添加特征描述测试。
- 修复 Bug 时,添加能够捕获该 Bug 的回归测试。
- 将被忽略、不稳定或跳过的测试视为尚未解决的问题。
- 测试中的童子军规则:让测试套件比你接手时更整洁。
错误与故障处理
- 区分:程序员错误(断言)、契约违规(panic/fail)、预期的领域故障(return/result 类型)、可重试故障和永久性故障。
- 将每个依赖、超时、重试、队列和降级状态都视为可能以缓慢、部分或长时间的方式发生故障。
- 对所有出站调用设置超时。禁止无限等待。使用有限次数的重试,并采用指数退避和随机抖动。切勿重试验证错误或永久性故障——应区分可重试与不可重试的结果。
- 在信任边界验证外部输入。绝不信任进程外部数据的结构、大小或语义。
- 如果继续执行会掩盖不可恢复的问题,就应快速失败。只有在具备监督和隔离机制时,才采用崩溃后恢复策略。
重构与变更
- 重构是在保留行为的前提下改进结构。切勿将功能开发或重新设计伪装成代码清理。
- 采用小步、可逆且可构建的方式推进。将超出局部推理能力范围的大型补丁拆分。
- 找出阻碍变更的结构性摩擦。只有在能让功能更安全或更简单时,才先于功能开发进行重构。
- 只针对当前阻碍因素,不要试图消除所有明显问题。当下一步清理带有推测性质时就停止。
- 当同一处修改第三次出现时,消除重复。
- 当模块超过约 400 行或承担 3 项以上不同职责时,进行拆分。若无法用一句话概括模块,它承担的职责就太多了——提取内聚的子概念。
- 优先采用最简单且命名明确的调整:重命名、提取、内联、移动、拆分或替换。
按书籍整理的精简规则
《代码整洁之道》(Martin)
关注可读性、局部推理和可维护性。纠正:「代码能运行 = 代码整洁。」
- 函数:只做一件事,保持单一抽象层级,按自上而下的叙述组织
- 命名:揭示意图、便于发音,每个术语只表达一个概念
- 不使用布尔标志、输出参数或隐藏副作用
- 注释只说明原因或约束,绝不用于叙述代码内容
- 测试作为生产代码:可读、确定、快速
- 童子军规则:让接触过的代码更整洁
《软件设计的哲学》(Ousterhout)
关注深模块、信息隐藏和复杂度降低。纠正:「熟悉的模式 = 简单。」
- 深模块:接口简洁,隐藏的复杂性有实际意义。拒绝薄封装。
- 将复杂性向下收拢到掌握相关细节的模块中
- 围绕调用方需要了解的内容设计接口,而不是围绕实现方式
- 通过更强的不变量减少异常面。让无效状态无法成立。
- 注释用于记录设计决策和隐藏的复杂性
- 命名、一致性和一目了然本身就是设计信息
Clean Architecture(Martin)
业务规则独立于框架、数据库和 UI。纠正:“细节就是架构。”
- 依赖指向内层。领域层绝不导入框架、数据库、UI 或供应商代码。
- 实体守护企业级不变量;用例编排单个操作
- 框架、数据库和交付机制都是外层细节,置于端口/适配器之后
- 内层拥有接口;外层实现接口
- 不要通过共享来合并用例;不同参与者导致的重复应予以保留
- 核心测试无需真实数据库、网络、框架或硬件即可运行
Code Complete(McConnell)
规范构建、减少缺陷、编写可验证的代码。纠正:“敲代码就是构建。”
- 对复杂例程,先用一致的抽象层级绘制伪代码草图
- 在每个信任边界验证输入。用断言表达程序员的假设。
- 在恰当的抽象层级处理错误。绝不在发生损坏后默默继续。
- 复杂度上升就是缺陷风险上升。拆分纠缠在一起的例程。
- 以小步构建,每一步都可验证。频繁集成。
- 注释解释意图、约束和契约,而非实现机制。
Domain-Driven Design(Evans)+ DDD Distilled(Vernon)
通用语言、限界上下文、战术模式。纠正:“模型就是数据架构。”
- 在解释任何术语或模块前,先命名限界上下文
- 在上下文中,每个概念只对应一个术语。代码应使用通用语言。
- 聚合:规模小、只有一个根、受不变量保护;默认每个事务处理一个聚合
- 值对象:不可变、在构造时验证、按值比较
- 仓储返回领域对象,而非表或 ORM 行
- 领域事件:用过去时表述的业务事实,而非属性变更通知
- 在每个上下文边界设置防腐层
- 核心领域采用更丰富的建模;支撑子域保持简单
Implementing DDD(Vernon)
实用 DDD:聚合、事件、服务、持久化。纠正:“给 CRUD 改个名字就是 DDD。”
- 通过标识引用其他聚合,而非对象图
- 对不适合由任何实体或值对象承担的操作,使用领域服务
- 应用服务协调用例,不负责领域决策
- 只有在一致性或表示需求足以证明其合理时,才使用 CQRS 拆分模型
- 只有当事件序列确实是合适的持久化模型时,才使用事件溯源
- 直接测试不变量、有效/无效状态转换和事件
Patterns of Enterprise Application Architecture(Fowler)
分层和企业应用模式。纠正:“模式越多,设计越好。”
- 根据业务逻辑的实际需求选择模式:事务脚本 → 表模块 → 领域模型
- 使用服务层协调用例并划定事务边界
- 仓储使用领域术语;数据映射器确保 SQL 不进入领域对象
- 工作单元用于一次逻辑提交;标识映射确保每个作用域内一个标识仅对应一个对象
- 在跨层边界使用远程外观 + DTO,绝不泄露领域内部细节
- 审慎选择会话状态的存放位置:客户端、服务端或数据库,并考虑扩展性
Refactoring(Fowler)
保持行为不变的结构改进。纠正:“清理代码就是重写。”
- 保持可观察行为不变。将行为变更与结构变更隔离。
- 采用小步、可逆、可测试的改动。高风险工作前先建立安全网。
- 预备性重构:在实现功能前,先调整阻碍工作的结构
- 针对当前造成阻碍的代码异味,而非所有显而易见的异味
- 采用最简单的命名重构手法:重命名、提取、内联、移动、封装、替换
- 当所请求的变更已很容易实现,且阻碍性的代码异味已消除时,就停止
高效处理遗留代码 (Feathers)
在未经测试的代码中安全地修改。纠正:“先重写再说。”
- 遗留代码 = 缺乏可信测试的代码。重新设计前先刻画其行为。
- 找到或创建接缝:无需编辑周边代码即可改变行为的位置
- 修改前先打破那个阻碍修改的依赖
- 插入代码时使用 Sprout Method、Sprout Class、Wrap Method、Wrap Class
- 让该区域比接手时更易于测试
- 拒绝:隐藏依赖扩张、只有表面功夫的重构、大规模重写
设计数据密集型应用 (Kleppmann)
分布式数据、一致性、事件、复制。纠正:“一切都是本地的/有序的/恰好一次的。”
- 必须明确真实数据源、派生表示形式和一致性预期
- 将崩溃、部分写入、重复和超时视为正常输入
- 明确写入语义:何时持久化?何时可见?如何处理冲突?是否允许读取过期数据?
- 事件描述事实。消费者应能容忍延迟、重复、重放和带版本的负载。
- 架构、API 和事件应能在新旧读取方/写入方之间演进
- 根据与工作负载相关的局部性进行分区;明确热门键和跨分区成本
- 根据实际不变量匹配事务和隔离级别,不要一概采用默认设置
Release It! (Nygard)
生产环境可靠性、稳定性模式。纠正:“快乐路径 = 已达到生产就绪状态。”
- 每个出站调用都设置超时。不要无限等待。使用带退避的有限重试。
- 使用熔断器、隔舱和快速失败来隔离依赖故障
- 设计过载处理方式:有限队列、负载削减,为关键流量预留容量
- 启动、健康检查、迁移和运维控制都应可重启、可观测
- 信任外部响应前,先校验其结构、合理性和语义
- 在每个边界进行可观测性监控:延迟、饱和度、错误、队列深度、熔断器状态
程序员修炼之道 (Hunt & Thomas)
工程实践、责任担当、自动化。纠正:“本地编辑 = 完成。”
- 每项事实只保留一个权威来源。其他内容都应由此派生或追溯到此。
- 保持正交性:组件彼此独立、接口精简、关注点分离
- 优先使用追踪弹,而非堆砌孤立部件。尽早端到端验证架构。
- 将重复、易出错、容易忘记的工作自动化
- 缩短反馈周期:相关测试、自动检查、低成本的早期信号
- 破窗效应:在小幅质量衰退成为常态前修复它,或明确控制其影响
- 根据复现的事实调试:观察、隔离、解释、修复、验证
Refactoring.Guru
代码异味目录和技术目录。纠正:“模式 = 永远适用的答案。”
- 选择技术前先诊断代码异味
- 优先采用最简单的处理方式:先重命名,再提取;先提取,再重新设计
- 每种代码异味都有特定的根本原因和处理路径
- 完整目录参见
references/refactoring-guru.full.md
兼容性指南
相互冲突的书籍(不要将其作为同等指导同时加载):
- DDD ❌ PoEAA — 数据所有权范式不同
- IDDD ❌ PoEAA — 在实现层面存在相同冲突
内容重叠的书籍(任选一本,它们强调的方向相似):
- Clean Code 🔁 Pragmatic Programmer、Code Complete、APoSD — 代码质量
- DDD 🔁 DDD Distilled、IDDD — 不同深度的 DDD;按需选择所需层次
- Clean Architecture 🔁 IDDD、PoEAA — 架构/分层内容重叠
- Refactoring 🔁 Refactoring.Guru — 代码改进;选择 Refactoring 获取策略,选择 Guru 获取目录
其他所有书籍组合都互为补充。默认做法:始终加载一本主要书籍,其他书籍 则根据任务按需加载。
本地参考文件
每本书的迷你规则集都作为本地参考文件存放在
references/ 下。加载文件的方法:
skill_view(name='programming-principles', file_path='references/{book-dir}.mini.md')
| 文件 | 书籍 |
|---|---|
references/a-philosophy-of-software-design.mini.md | A Philosophy of Software Design |
references/clean-architecture.mini.md | Clean Architecture |
references/clean-code.mini.md | Clean Code |
references/code-complete.mini.md | Code Complete |
references/designing-data-intensive-apps.mini.md | Designing Data-Intensive Applications |
references/domain-driven-design.mini.md | Domain-Driven Design |
references/domain-driven-design-distilled.mini.md | DDD Distilled |
references/implementing-domain-driven-design.mini.md | Implementing DDD |
references/patterns-of-eaa.mini.md | Patterns of Enterprise App Architecture |
references/refactoring.mini.md | Refactoring |
references/refactoring-guru.mini.md | Refactoring.Guru |
references/release-it.mini.md | Release It! |
references/the-pragmatic-programmer.mini.md | The Pragmatic Programmer |
references/working-effectively-with-legacy-code.mini.md | Working Effectively with Legacy Code |
references/code-assessment-workflow.md | 评估方法——并非书籍,而是将所有书籍的内容结合起来应用于真实代码库的工作流 |
每本书还有一个完整版本(11-42 KB),可在需要时用作深入参考。按需加载:
skill_view(name='programming-principles', file_path='references/{name}.full.md')
注意:references/refactoring-guru.full.md 是一个索引,会指向两个分篇文件(refactoring-guru.full-smells-and-priorities.md 和
refactoring-guru.full-technique-playbook-and-safety.md)。加载索引后会显示“本参考资料的分篇”表格;然后加载所需的具体分篇。
| 完整文件 | 书籍 | 大小 |
|---|---|---|
references/a-philosophy-of-software-design.full.md | A Philosophy of Software Design | 13 KB |
references/clean-architecture.full.md | Clean Architecture | 17 KB |
references/clean-code.full.md | Clean Code | 13 KB |
references/code-complete.full.md | Code Complete | 12 KB |
references/designing-data-intensive-apps.full.md | Designing Data-Intensive Applications | 16 KB |
references/domain-driven-design.full.md | Domain-Driven Design | 42 KB |
references/domain-driven-design-distilled.full.md | DDD Distilled | 11 KB |
references/implementing-domain-driven-design.full.md | Implementing DDD | 12 KB |
references/patterns-of-eaa.full.md | Patterns of Enterprise App Architecture | 15 KB |
references/refactoring.full.md | Refactoring | 17 KB |
references/refactoring-guru.full.md | Refactoring.Guru | 索引 + 2 个分篇 |
references/release-it.full.md | Release It! | 13 KB |
references/the-pragmatic-programmer.full.md | The Pragmatic Programmer | 13 KB |
references/working-effectively-with-legacy-code.full.md | Working Effectively with Legacy Code | 13 KB |
渐进式披露模式:日常指导时加载迷你文件(触发条件、决策规则、最终检查清单)。仅在深度研讨、审计或需要包含代码异味索引和技术参考的完整规则目录时加载完整文件。
已知弱点(来自代码库评议)
- 没有对改进效果进行实证测量——这些规则基于原则,而非基准测试。应自行判断这些规则是否能改善实际结果。
- 一次加载过多规则集会导致上下文饱和。最多使用一套始终启用的主要规则集,再加一套按需加载的任务专用规则集。
- 规则源自书籍,而非实际故障。最有价值的 Agent 规则来自真实失败,而非理论。
- 存在伪合规风险:Agent 遵循规则字面要求,却忽略了实际任务。应根据真实需求测试输出,而非检查其是否符合规则。