第一章:务实的哲学
这一章奠定了务实编程的基石——它是一种态度、风格和解决问题的方法。务实的程序员会超越眼前的问题,寻求更大的背景和蓝图。
主题 1: 这是你的人生
你的职业生涯由你掌控。务实的程序员主动塑造自己的职业道路,而不是被动接受。
主题 2: 猫吃了我的源代码
务实哲学的基石之一是为自己的行为负责。承担责任,不找借口,是建立团队信任的关键。
主题 3: 软件熵
软件和物理世界一样会趋向无序,即“软件腐烂”或“技术债务”。项目心理学是导致腐烂的重要因素。“破窗效应”表明,一个未修复的小问题会迅速引发更多问题,导致整个系统的衰败。
主题 4: 石头汤与煮青蛙
这个主题讲述了两种关于变化的寓言。石头汤教我们如何成为变革的催化剂:从一个小的、可行的请求开始,展示成功,然后逐步吸引他人加入,最终达成宏伟目标。而煮青蛙则是一个警示:要警惕渐进式的衰败,持续关注大局,否则会在不知不觉中陷入困境。
主题 5: 足够好的软件
追求完美可能导致项目延期甚至失败。通常,用户宁愿今天就用上一个有一些瑕疵的软件,也不愿为“完美”的版本等上一年。关键在于让用户参与决策,确定何时软件“足够好”。
主题 6: 你的知识组合
知识和经验是会过期的资产。你需要像管理金融投资组合一样管理你的知识:定期投资、多元化、管理风险、低买高卖、定期回顾和重新平衡。
主题 7: 沟通!
有效的沟通至关重要。你需要了解你的听众,知道你想说什么,选择合适的时机和风格。文档也是沟通的一种形式,应该内建于开发过程中,而不是事后添加。
第二章:务实的方法
本章介绍了一些通用的软件开发原则和技巧,它们是务实编程的核心实践。
主题 8: 好设计的本质
所有设计原则的本质都可以归结为一个简单的原则:ETC (Easier to Change),即“更容易修改”。
主题 9: DRY——重复的危害
DRY 原则(Don't Repeat Yourself)是务实编程最重要的工具之一。它不仅仅指代码的复制粘贴,更关乎知识和意图的重复。
主题 10: 正交性
正交性意味着系统中的组件是相互独立、解耦的。修改一个组件不应影响其他不相关的组件。正交的系统能提高生产力并降低风险。
主题 11: 可逆性
世界在不断变化,关键决策并非一成不变。我们应该构建灵活、适应性强的软件,避免做出无法挽回的决定。例如,将数据库抽象为一个持久化服务,而不是将代码与特定供应商绑定。
主题 12: 曳光弹
对于充满未知的项目,与其进行过度设计,不如采用“曳光弹”开发方法。快速构建一个能贯穿系统所有架构层的、简陋但完整的端到端功能骨架。这能让你获得早期反馈,验证架构,并为团队提供一个可以逐步填充的工作框架。曳光弹代码是产品代码的一部分,不是一次性的原型。
主题 13: 原型与便利贴
原型是为了学习和探索风险而创建的一次性代码或模型。它可以用来测试架构、算法、界面或想法。原型的价值在于其过程中的学习,而不是产出的代码本身。
主题 14: 领域语言
编程语言影响我们思考问题的方式。如果能使用贴近问题领域的词汇、语法和语义来编程,代码会变得更清晰、更易于理解。这可以通过创建内部DSL(领域特定语言)或使用外部DSL(如YAML、JSON)来实现。
主题 15: 估算
估算是一项重要的技能,能帮助我们避免意外。估算不是一个精确的数字,而是一个带有上下文和准确性预期的范围。对于项目排期,迭代式开发是获得准确估算的最好方法,随着项目的进行不断修正估算。
第三章:基本工具
工具能放大你的才能。一个务实的程序员应该精通一套基本工具,并让它们成为自己能力的延伸。
主题 16: 纯文本的力量
知识是我们的原材料,而存储知识的最佳格式是纯文本。它能避免技术过时,利用现有工具,并简化测试。
主题 17: Shell 游戏
命令行 Shell 是程序员的工作台。精通 Shell 可以让你自动化常见任务,组合各种工具,发挥出 GUI 无法比拟的强大威力。
主题 18: 强力编辑
编辑器是你使用最频繁的工具。达到“编辑器流畅”的境界,意味着你不再需要思考编辑的机械动作,思想可以直接流淌为代码。
主题 19: 版本控制
版本控制系统是项目的“时间机器”,是巨大的撤销键。所有东西——代码、文档、配置文件、脚本——都应该纳入版本控制。它不仅仅是备份,更是团队协作、构建和发布流程的核心枢纽。
主题 20: 调试
调试是一种解决问题的过程,而不是互相指责。要抱着解决问题的心态,而不是恐慌。在修复一个 bug 之前,先编写一个能够复现它的测试。
主题 21 & 22: 文本处理 & 工程日志
学习一门文本处理语言(如 Python、Ruby)可以极大地提高生产力。同时,保持一本工程日志(纸质为佳),记录你的工作、想法和学到的东西,这比记忆更可靠。
第四章:务实的偏执
我们无法写出完美的软件。接受这个事实,并采取防御性编程,不仅要防范外部错误,也要防范我们自己的错误。
主题 23: 契约式设计 (DBC)
DBC 是一种通过为软件模块定义精确的、可验证的接口规范来确保程序正确性的技术。它包含前置条件、后置条件和类不变量。
主题 24: 消亡的程序不撒谎
一个崩溃的程序造成的损害,通常远小于一个带病运行的程序。当代码发现“不可能”发生的事情时,程序已经不再可靠,应该尽快终止它。
主题 25: 断言式编程
当你认为“这绝不可能发生”时,就用代码来检查它。断言是检查那些理论上不应发生的情况的有效工具。不要在生产环境中关闭断言。
主题 26: 如何平衡资源
资源管理(内存、文件句柄、数据库连接等)遵循一个简单的模式:分配、使用、释放。谁分配资源,谁就负责释放资源。
主题 27: 不要超越你的前灯
我们对未来的预测能力有限,就像车灯只能照亮前方一小段路。开发时要始终采取小的、可验证的步骤,并根据反馈进行调整。你的反馈速率就是你的速度极限。
后续章节核心要点
第五章:可弯曲,不折断(Bend, or Break)
- 解耦 (Decoupling): 紧密耦合的代码难以修改。通过“告知,不要询问”(Tell, Don't Ask)原则和避免方法链式调用来减少耦合。
- 转换式编程 (Transforming Programming): 将程序视为一系列数据转换的管道,而不是一堆相互作用的对象。这能减少状态的持有,降低耦合。
- 继承税 (Inheritance Tax): 继承是面向对象语言中最强的耦合。优先使用接口、委托或混入 (Mixins) 来实现多态和代码共享。
- 配置 (Configuration): 将易变的细节(如数据库凭证、税率、特性开关)外部化到配置文件中,使应用无需重新编译即可适应变化。
第六章:并发(Concurrency)
- 打破时序耦合 (Breaking Temporal Coupling): 通过分析工作流,识别可以并行执行的活动,让你的设计能够容纳并发。
- 共享状态是错误状态 (Shared State Is Incorrect State): 并发问题的根源在于可变的共享状态。并发访问需要通过信号量、互斥锁等机制来保护。
- Actor 与进程 (Actors and Processes): 使用 Actor 模型可以实现无共享状态的并发。每个 Actor 都是一个独立的计算单元,通过异步消息进行通信。
- 黑板 (Blackboards): 对于复杂的工作流,可以使用黑板系统来协调。各个独立的“专家”代理从黑板上获取数据,处理后将新数据放回,共同推动问题的解决。
第七章:编码时(While You Are Coding)
- 听从你的蜥蜴脑 (Listen to Your Lizard Brain): 关注你的直觉和潜意识。如果你对某段代码感到不安或觉得它写起来异常困难,停下来思考一下,这可能是你的经验在发出警告。
- 通过巧合编程 (Programming by Coincidence): 不要依赖巧合或未明确定义的行为。要刻意地编程,清楚地知道代码为什么能工作。
- 重构 (Refactoring): 编码更像是园艺而不是建筑。代码需要持续地照料和修整。当你学到新东西或发现可以改进的地方时,尽早重构,频繁重构。
- 为测试而编码 (Test to Code): 测试的主要好处不是找到 bug,而是在你思考和编写测试时获得的设计反馈。测试是你代码的第一个用户。
- 属性测试 (Property-Based Testing): 除了编写基于示例的单元测试,还可以使用属性测试。定义代码应遵守的属性(不变量、契约),然后让框架生成大量随机数据来验证这些属性。
- 命名 (Naming Things): 好的命名至关重要。它揭示了你的意图。当事物的角色或意义发生变化时,要及时重命名。
第八、九、十章:项目与责任
- 需求之坑 (The Requirements Pit): 没有人确切知道自己想要什么。需求是在反馈循环中学习到的。你的工作是帮助人们理解他们想要什么。
- 敏捷的本质 (The Essence of Agility): 敏捷不是一个名词,而是你做事的方式。它的核心是:1. 弄清你在哪里。2. 朝你想去的地方迈出最小且有意义的一步。3. 评估结果,并修正。
- 务实的启动工具包 (Pragmatic Starter Kit): 每个项目都应建立在三个支柱上:版本控制、回归测试和完全自动化。
- 取悦用户 (Delight Your Users): 你的目标不仅仅是交付代码,而是通过软件解决用户的业务问题,超出他们的预期。
- 在你的作品上签名 (Sign Your Work): 为你的工作感到自豪。你的名字应该成为质量的标志。
- 道德责任 (Moral Compass): 作为未来的构建者,我们有责任思考代码带来的影响。“首先,不要造成伤害”,以及“不要为流氓提供便利”。