mcpField
P
pragmatic-programmer

pragmatic-programmer

github.com/wondelai开发2.5k5.8k 次安装7 周前更新
代码仓库

关于 pragmatic-programmer

面向开发者和工程团队的软件工艺技能,借鉴《The Pragmatic Programmer》指导架构、代码审查与工程实践。它强调让系统易于理解和变更的习惯,并提供原则诊断及改进方向。

主要功能

  1. 01用 DRY 识别知识重复
  2. 02设计正交组件
  3. 03采用示踪弹与原型
  4. 04定义契约和断言
  5. 05处理破窗与技术债
  6. 06优先选择可逆决策并采用区间估算

适用场景

  1. 01审查架构耦合与变更影响
  2. 02规划端到端的精简实现
  3. 03设定模块前置条件与不变量
  4. 04评估供应商选择和工期估算

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/wondelai/skills --skill pragmatic-programmer

安装后在 Claude Code 中输入/pragmatic-programmer确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
broken-windows.md
contracts-assertions.md
dry-orthogonality.md
estimation-portfolio.md
reversibility.md
tracer-bullets.md

详细介绍

The Pragmatic Programmer 框架

Hunt 和 Thomas 的《The Pragmatic Programmer》(20 周年纪念版)提出的软件工艺系统级方法。在设计系统、评审架构、编写代码或为工程文化提供建议时,应用这些元原则——思考如何理解软件,而不只是如何编写软件。

核心原则

关心自己的工艺。 软件开发要求持续学习、严谨实践和个人责任——务实的程序员不会只关注眼前的问题,还会考虑上下文、权衡取舍和长期影响。优秀的软件源于良好的习惯:坚决避免重复,保持组件正交,并将每一行代码都视为必须证明其价值的活资产。目标不是追求完美,而是打造易于修改、易于理解、值得信赖的系统。

评分

目标:10/10。 根据七项快速诊断逐项评分:每项回答“是”得约 1.4 分(7 项均为“是”即得 10 分)。然后按以下区间划分结果:

  • 9-10:所有原则均得到遵守——知识符合 DRY、各层正交、有可运行的 tracer 切片、边界处有契约、没有破窗、供应商和数据库选择可逆、估算有范围。
  • 5-6:存在 1-2 项会造成实际变更成本的违规(例如业务逻辑与数据库耦合、只给出单点估算)。
  • <=3:重复无处不在、存在全局状态,或破窗不断累积——熵正在占上风。

始终说明评分,指出未通过的诊断项,并给出“行动”栏中列出的具体修复措施,以达到 10/10。

七大元原则

构建持久软件的七项原则:

1. DRY(Don't Repeat Yourself,不要重复自己)

核心概念: 系统中的每一项知识都必须有且只有一个明确、权威的表示。DRY 针对的是知识,而非代码——重复的逻辑、业务规则或配置远比重复的语法危险。

有效原因: 重复的知识必须在多个地方修改;迟早会有一处被遗漏,导致不一致。DRY 能缩小 bug 的影响范围,让系统更易于修改。

关键见解:

  • DRY 适用于知识和意图,而非文本相似性——两个相同的代码块若服务于不同的业务规则,就不属于重复
  • 重复有四种类型:外部强加(环境导致)、无意造成(开发者没有意识到)、急于求成(懒得抽象)和开发者间重复(多人各自重复实现)
  • 复述代码内容的注释违反 DRY——应解释为什么,而非是什么
  • 数据库架构、API 规范和文档都会造成知识重复,除非它们由单一来源生成
  • DRY 的反面是 WET:“Write Everything Twice”(所有内容都写两遍)或“We Enjoy Typing”(我们乐于敲代码)

代码应用:

上下文模式示例
配置值单一事实来源在一个 env 文件中设置数据库连接,并在各处引用
验证规则共享架构客户端和服务器共用一个 JSON Schema 或 Zod 架构
API 契约根据规范生成使用 OpenAPI 规范生成类型、文档和客户端代码

参见:references/dry-orthogonality.md,用于判断具体的重复情况,或确定两个代码块是否确实表达了相同的知识——其中提供了四种重复类型各自的示例和缓解措施。

2. 正交性

核心概念: 如果一个组件的变化不会影响另一个组件,那么这两个组件就是正交的。设计自包含、相互独立且用途明确的系统组件。

为何有效: 解耦能将变化限制在局部——一个模块中的修复不会波及无关模块,因此影响范围始终可控。修改数据库层不应导致 UI 出错;更换身份验证提供方,业务逻辑也不应受影响。

关键见解:

  • 思考:“如果我大幅更改某个函数背后的需求,会影响多少个模块?”答案应该是一个
  • 消除无关事物之间的影响——日志记录的更改绝不应导致计费出错
  • 分层架构有助于实现正交性:表示层、领域逻辑、数据访问层
  • 避免全局数据——每个使用全局状态的使用方都会与之耦合
  • 强制要求继承其类的框架会降低正交性

代码应用:

场景模式示例
架构分层分离Controller -> Service -> Repository,每层都可替换
依赖依赖注入传入 Notifier 接口,而不是 SlackClient 具体类
测试隔离的单元测试不依赖数据库、网络或文件系统来测试业务逻辑

参见:references/dry-orthogonality.md,了解如何衡量耦合度或重构为解耦的层——其中包括变更影响测试与陌生人测试、分层架构图以及直升机类比。

3. 曳光弹与原型

核心概念: 曳光弹是贯穿系统所有层、功能精简的端到端实现。与一次性原型不同,曳光弹代码是生产代码——轻量但真实。

为何有效: 曳光弹能让你在投入完善每项功能之前,立即获得端到端反馈。用户能看到真实的成果,开发者有了可供构建的框架,集成问题也能及早显现。

关键见解:

  • 曳光弹:贯穿系统(UI -> API -> DB)的精简但完整路径——保留使用
  • 原型:针对单个高风险方面进行探索——完成后丢弃
  • 在“摸黑开火”时使用曳光弹——例如需求模糊或架构尚未验证时
  • 如果曳光弹没命中,就调整后再次发射——迭代成本很低
  • 明确标注原型仅供丢弃——绝不能让原型成为生产代码

代码应用:

场景模式示例
新项目纵向切片一个端到端功能:按钮 -> API -> DB -> 响应
技术尚不确定Spike 原型在决定采用 WebSocket 之前测试其性能
微服务行走骨架让 Hello-world 服务跑通完整的 CI/CD 流水线

参见:references/tracer-bullets.md,了解在新项目中如何选择曳光弹或原型,或如何构建行走骨架——其中包括“摸黑开火”的决策方法、迭代循环和常见陷阱。

4. 契约式设计与断言式编程

核心概念: 通过前置条件(之前必须满足的条件)、后置条件(之后能够保证的条件)和不变量(始终成立的条件),定义并强制执行软件模块的权利与责任。契约遭到违反时,立即明确地失败。

为何有效: 契约能让假设明确化。系统不会悄悄破坏数据,也不会在无效状态下勉强运行,而是在问题发生处直接崩溃——已停止运行的程序不会说谎。

关键见解:

  • 前置条件:调用方的责任——“我只接受正整数”
  • 后置条件:例程的保证——“我会返回一个已排序的列表”
  • 不变量:始终成立——“账户余额永远不会为负”
  • 尽早崩溃:停止运行的程序造成的损害远少于瘫痪的程序
  • 对绝不应发生的情况使用断言;对可能发生的情况使用错误处理
  • 在动态语言中,通过运行时检查和守卫子句实现契约

代码应用:

场景模式示例
函数入口前置条件守卫在函数开头使用 assert age >= 0, "Age cannot be negative"
类状态不变量验证每次状态变更后调用 validate!
API 边界模式验证处理请求前,根据模式验证请求正文

参见:references/contracts-assertions.md,了解何时为例程添加契约,或如何在断言与错误处理之间做选择——其中包含前置条件、后置条件和不变量的示例模式、动态语言中的守卫子句,以及断言与错误处理的适用边界。

5. 破窗理论

核心概念: 一扇破窗——设计糟糕的代码、错误的管理决策,或“以后再修”的权宜之计——会开启腐化的开端。一旦系统显露出被忽视的迹象,熵就会加速,纪律也会瓦解。

为何有效: 这是心理作用。代码整洁时,开发者会感受到保持整洁的社会压力;代码已经杂乱时,继续制造混乱的门槛就会降至零。质量是团队习惯,而非个人英雄主义。

关键见解:

  • 不要让破窗(糟糕的设计、错误的决策、质量低劣的代码)得不到修复
  • 如果现在无法修复,就先把它封起来:添加附带工单的 TODO、禁用功能,或使用存根
  • 成为变革的催化剂:向大家展示未来可行的样子(石头汤)
  • 留意缓慢退化(温水煮青蛙)——持续监控技术债指标
  • 第一个权宜之计代价最高,因为它为之后所有的权宜之计开了先例

代码应用:

场景模式示例
遗留代码封住破窗添加功能前,先用整洁的接口封装糟糕的代码
代码审查对新增技术债零容忍拒绝添加 // TODO: fix later 却没有关联工单的 PR
技术债技术债预算每个 sprint 拿出 20% 的时间修复破窗

参见:references/broken-windows.md,了解团队何时开始将忽视问题视为常态,或需要推动扭转局面——其中包含修复策略、“石头汤”催化方法,以及如何建立质量文化。

6. 可逆性与灵活性

核心概念: 没有最终决定。构建系统,让你可以轻松改变对数据库、框架、供应商、架构和部署目标的选择——变更成本应与变更范围成正比。

为何有效: 需求会变化,供应商会被收购,技术也会失宠。如果你的架构将其中任何假设硬编码进去,每次变更都会变成重写;灵活的架构将决策视为配置,而非结构。

关键见解:

  • 将第三方依赖抽象在自己的接口之后——绝不让供应商 API 渗入业务逻辑
  • “岔路口”测试:你能在一周内从 Postgres 切换到 DynamoDB 吗?如果不能,说明耦合过紧
  • 由元数据驱动的系统(配置文件、功能标志)比硬编码逻辑更灵活
  • YAGNI 同样适用于过早抽象——暂时不需要的灵活性,不要提前构建
  • 可逆性不是预测未来,而是不把自己逼入死角

代码应用:

场景模式示例
数据库Repository 模式业务逻辑调用 repo.save(user),而不是 pg.query(...)
外部 API适配器/包装器PaymentGateway 接口封装 Stripe;之后可切换到 Braintree
功能标志运行时开关将新的结账流程置于功能标志之后,几秒内即可回滚

参见:references/reversibility.md,了解提交采用某个供应商或框架时,或权衡决策需要多大程度的可逆性时可参考的内容——包括分层可逆性模式、“岔路口”测试,以及何时不应以可逆性为优化目标。

7. 估算与知识投资组合

核心概念: 通过理解范围、构建模型、拆分组件并设定区间,学会可靠地估算。像管理金融投资组合一样管理学习:定期投入、分散配置并重新平衡。

为何有效: 诚实的估算能建立与利益相关者之间的信任(“1-3 周”胜过自信却错误的“2 周”)。知识投资组合能让你在技术变迁时保持竞争力——停止学习的程序员也会逐渐失去效能。

关键见解:

  • 问问“这个估算用于什么?”——场景决定精度(预算规划还是迭代规划)
  • 使用 PERT:(乐观估算 + 4 × 最可能估算 + 悲观估算)/ 6
  • 拆分为多个组件并分别估算;总和比单次猜测更准确
  • 记录估算日志:将估算与实际情况对比并进行校准
  • 投资组合规则:定期投入(每周学习)、拓宽技能范围、不局限于当前技术栈,兼顾稳健和投机型选择,尽早学习新兴技术(低价买入)

代码应用:

场景模式示例
迭代规划区间估算“3-5 天”,并注明置信度,而不是给出单一数字
新技术限时探索“花 2 天评估;之后我就能准确估算”
学习每周投入每周花 1 小时学习一门新语言、一种新工具或一个新领域

参见:references/estimation-portfolio.md,了解如何给出需要承担责任的估算,或校准过去的估算偏差——包括 PERT 和拆分步骤、估算日志校准循环,以及投资组合再平衡。

常见错误

错误失败原因修正方法
将用途不同但看起来相似的代码 DRY 化耦合了无关概念;修改一处会破坏另一处只对知识应用 DRY,而非巧合的代码相似性
跳过追踪弹,逐层构建集成问题很晚才会浮现;缺少端到端反馈先构建一个精简的垂直切片
因为“以后会重构”而忽视破窗熵会加速增长;以后永远不会到来;士气会下降立即修复,或用有跟踪记录的工单将其封起来
将估算作为单点承诺未能兑现时,虚假的精确性会侵蚀信任始终提供范围和置信度
一开始就让所有东西都“灵活”过度设计;没有证据表明需要抽象有具体证据表明需要灵活性时再添加
“为了性能”而移除生产环境断言断言原本能捕获的错误会悄悄破坏数据保留关键断言;移除前先进行基准测试
为了“方便”而使用全局状态破坏正交性;一切都彼此耦合使用依赖注入和显式参数

快速诊断

问题如果否行动
我能否在不触及业务逻辑的情况下更改数据库?违反正交性引入仓储/适配器模式
我是否有一个可运行的端到端切片?缺少追踪弹扩展之前先构建一个垂直切片
每条业务规则是否都只在一个地方定义?违反 DRY找出权威来源;移除重复项
新开发者会称这个代码库“整洁”吗?存在破窗安排专门的清理冲刺
我的估算是否包含范围和置信度?估算有问题改用 PERT 或基于范围的估算
我能否在 5 分钟内回滚此次部署?可逆性不足添加功能标志和蓝绿部署
我是否每周都在学习新东西?知识储备停滞安排每周学习时间并跟踪进度

延伸阅读

关于作者

Andrew Hunt 和 David Thomas 共同创立了 Pragmatic Bookshelf,也是《敏捷宣言》17 位原始作者中的两位。Thomas 创造了“DRY”和“Code Kata”这两个说法,并合著了 Programming Ruby(Pickaxe 一书);Hunt 专注于团队如何学习、沟通和维护质量。他们共同撰写了 The Pragmatic Programmer,这是有史以来最具影响力的软件书籍之一。

评论

支持 Markdown