这本书不是教你写代码的
《程序员修炼之道:从小工到专家》(The Pragmatic Programmer)1999 年首版,2020 年出了 20 周年纪念版。它不教你具体语言或框架,而是教你怎样像一个专业程序员一样思考。
以下是我在多年实践中反复验证过的核心原则。
1. DRY — 不要重复自己
Don't Repeat Yourself 是最容易被理解但最常被违反的原则。
重复不只是"复制粘贴代码"。它在多个层面存在:
| 层面 | 重复的表现 | 后果 |
|---|---|---|
| 代码 | 相同逻辑出现在多处 | 改一处忘另一处 |
| 数据 | 同一信息存储在多个地方 | 数据不一致 |
| 知识 | 同一业务规则在代码和文档中各写一次 | 文档与代码脱节 |
原则:系统中的每一项知识,都必须有唯一、明确、权威的表示。
2. 正交性
两个事物是正交的,如果改变其中一个不影响另一个。就像直升机的旋翼控制——前后和左右是独立的(正交的),而不是耦合的。
在代码中:
- 数据库代码不应该知道 UI 的存在
- 业务逻辑不应该依赖 HTTP 请求格式
- 日志组件不应该影响业务流程
自检方法:问自己"如果我显著改变某个模块的需求,会影响多少其他模块?"如果答案是"很多",你的系统缺乏正交性。
3. 曳光弹开发
不是原型,不是 Spike。曳光弹是最终架构中的一条端到端的 thin slice:
用户界面 → 业务逻辑 → 数据库
从第一行代码开始就贯穿所有层,用真实的数据、真实的接口、真实的部署流程。它能帮你:
- 验证架构是否走得通
- 让用户尽早看到真实的(虽然简陋的)系统
- 建立开发节奏和信心
曳光弹不是一次性代码——它是最终产品的骨架,会一直演化。
4. 防御性编程
核心思想:永远不要假设外部输入是正确的。
java
// ❌ 假设调用者会传正确的值
public void setAge(int age) {
this.age = age;
}
// ✅ 防御性编程
public void setAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("Invalid age: " + age);
}
this.age = age;
}
关键策略:
- 契约式设计(Design by Contract) — 明确前置条件、后置条件和不变式
- 尽早崩溃(Crash Early) — 发现问题时立刻失败,不要让错误传播
- 断言 — 在开发阶段用断言捕获不可能的状态
5. 知识投资组合
把你的知识当作投资组合来管理:
| 策略 | 说明 |
|---|---|
| 定期投资 | 每天固定时间学习,哪怕 15 分钟 |
| 多元化 | 不要只学一种语言/框架,T 型技能 |
| 管理风险 | 新技术(高风险高回报)+ 成熟技术(低风险稳定收益) |
| 低买高卖 | 在技术还没流行时就学习,成为早期专家 |
| 重新评估和平衡 | 定期检视,哪些该深入,哪些该放弃 |
每年至少学一门新语言——不需要精通,但不同的语言会改变你解决问题的方式。
6. 极限编程的核心实践
即使你不做 XP,这些实践也值得采纳:
- 测试优先 — 先写失败的测试,再写让它通过的代码
- 持续集成 — 每次提交都触发完整的构建和测试
- 重构 — 不是"有空再做",而是日常开发的一部分
- 结对编程 — 最好的 Code Review 是两个人一起写
7. Shell 游戏 — 善用命令行
专业的程序员应该流利使用命令行:
- 一个命令完成的事,不要写 GUI 工具
- 用 Shell 脚本自动化重复操作
- 熟悉
grep、sed、awk、find、xargs - 用
alias缩短常用命令
当你看到同事在终端里一秒钟完成你用 GUI 要点 20 次的操作时,你就知道命令行的价值了。
总结
程序员修炼之道的核心不是任何具体技术,而是一种职业态度:对自己的代码负责、持续学习、追求简洁、务实地解决问题。把这 7 个原则内化到日常开发中,你已经在从小工到专家的路上了。
