程序员修炼之道 / The Pragmatic Programmer

简介

《程序员修炼之道》是一本经典的软件开发实践指南,由 Andrew Hunt 和 David Thomas 两位著名软件工程师所著。这本书结合了作者多年的实践经验和深入思考,提出了许多宝贵的软件开发理念和方法论,成为了许多程序员必读的经典之作。

该书涵盖了诸如代码质量、架构设计、测试驱动开发、重构、模式应用等方面的内容,旨在帮助程序员从工匠的角度来看待软件开发问题,以更高效、更优雅的方式构建高质量的软件。

有感

这本书的每一节像是一颗知识宝珠,单独拎出来仔细琢磨、领悟,把这些十几个宝珠串起来就是一条美丽的项链,它的名字叫务实的程序员。

具体的技术实践、实施一定来源于独到的技术思想,它指引着我们构建强大、美丽的技术蓝图。作为一位老程序员,对书中诸多技术思想颇有共鸣,下面将每一节进行概括罗列:

务实的哲学

务实的程序员,在面对问题时,利用一些科学的态度、风格及理念,不局限于问题表面,而从大局出发综合考虑问题。

  • 1. 掌控人生:软件开发是最能掌控的职业之一
  • 2. 团队信任:信任是良好团队协作的基石,敢于承认错误、承担责任
  • 3. 破窗效应:破窗效应影响巨大,不要容忍任何破窗,及时修复发现的问题
  • 4. 石头汤:技术人员理想且偏执,可以利用石头汤循序渐进的推进项目
  • 5. 够用即可:不要追求一次性开发一个完美的软件,坚持 MVP 原则,写出够用即可的软件
  • 6. 学习:知识和经验是最重要的专业资产,但却是一种时效资产。因此,要不断学习进步,构建合理的知识组合。学习也是拓展思维的过程,打开全新可能性的大门,领悟新的做事方式。同时需要批判性思维,尽信书则不如无书。
  • 7. 沟通:以对方能理解的方式沟通,而不是以自己的理解夸夸其谈。

务实的方法

一些通用的编程思想、方法,虽然不是严格的规范,但遵循它们可以帮助我们更好的完成开发工作。

  • 8. ETC原则:优秀的设计要信奉ETC原则(Easier To Change,更容易变更)
  • 9. DRY原则:可靠且易维护的软件应遵循DRY原则(Don’t Repeat Yourself):在一个系统中,每一处知识都必须单一、明确、权威地表达。
  • 10. 低耦合高内聚:通过遵循”低耦合高内聚”的设计原则,可以使得软件系统更加健壮、可维护、可扩展和可重用。
  • 11. 可逆性:需求是写在沙滩上的,随时可能被推翻修改。技术方案要保持模块化的灵活性
  • 12. 曳光弹:采用 MVP 原则开发能快速、低成本地验证核心需求,曳光弹代码不是一次性的,虽然简单但是完整,是最终系统框架的组成部分。一旦曳光弹找到真实目标,再添加功能就容易多了。
  • 13. 原型:用来分析和暴露风险,尽量推迟思考细节,先将系统的各个部分整合起来。
  • 14. 无
  • 15. 估算进度:对于全新的系统一开始很难估算所需工时,因为进度是由团队、团队的生产力和环境综合决定的。一般需要完成初始功能开发及测试后提炼项目经验,再进行估算更合理,同时把提炼进度表作为每次迭代的一部分,估算也会越来越精确。大象是一口一口吃掉的。

基础工具

好的工匠需要有自己强大称手的工具箱,不断丰富的工具也是自身能力的延展。

  • 16. 无
  • 17. 无
  • 18. 善用编辑器:每次发现自己重复或耗时地做某件事件时,自省是否有更好的方法,发掘编辑器的有用特性(如快捷键、强大功能),并内化为肌肉记忆。
  • 19. 版本控制:永远使用版本控制!
  • 20. 修复bug:遇到bug不要慌,稳住心态。解决bug前,收集尽可能详细的报错信息或用户反馈。动手前,先复现bug。二分法、排除法提高修复效率。不要一直被bug卡住,找个橡皮鸭。永远发掘问题的根本原因,而不仅仅是表面。修复bug时可能会发现自身知识的盲区或误解,只能显著提升技术能力。
  • 21. 无
  • 22. 工程日记:将日常工作中的任务、想法记录到笔记本里,这样的工程日记能提高三个好处:比记忆更可靠,不会被遗忘;暂存与当前任务无关的想法,更专注;提供事后反思梳理的机会。

务实的偏执

永远不会有人写出完美的软件,别去浪费时间追逐一个不可能的梦想。接受一个存在缺陷的现实,利用契约、异常报错、小步前进等工具与现实保持一种动态平衡。

  • 23. 契约式设计:契约式设计(Design By Contract,简称DBC),是一种面向对象软件开发的设计思想。它通过在程序中添加前置条件、后置条件和不变式等契约元素,来明确代码对外提供的功能和行为,并且在运行时检查这些契约是否被满足。改善可维护性、可重用性和可靠性。
  • 24. 尽早崩溃:不要试图掩盖或忽略错误,应尽早抛出异常。这样,才能更快的查到并解决问题,同时对系统的损害也更小。
  • 25. 断言:用于检查程序正确性,快递定位问题有帮助,如 PHP 的 assert 断言函数。
  • 26. 资源平衡:资源使用遵循分配资源、使用它及释放它的模式,谁创建资源谁负责释放,嵌套创建的资源,释放与创建顺序是反向的。
  • 27. 小步前进:功能迭代采用深思熟虑的小步骤,检查真实反馈,并在不断调整中持续推进。步子不能太大,未来不确定性很多,与其预测未来,不如将代码设计为可替代性的。

宁弯不折

为了适应不断变化的业务需求,编写尽可能宽松、灵活的代码更可取,核心在于减少耦合。

  • 28. 解耦易于改变:管道命令替代链式调用,避免全局数据
  • 29. 观察者模式:发布/订阅(pubsub)推广了观察者模式,同时解决了耦合和性能问题。围绕事件并以异步事件流的方式编写代码比线性代码更容易响应、解耦更好。
  • 30. 函数式编程:相对面向对象,作者更喜欢函数式编程,理由是降低耦合、提高复用。我认为各有利弊,还需斟酌。
  • 31. 继承税:继承增加耦合,避免过分的继承,采用 interface、trait 等也能实现多态,同时降低耦合。
  • 32. 配置服务化:相对使用配置文件,配置服务化有鉴权、易维护、动态配置等诸多好处,较流行的配置服务化工具包有 携程 Apollo、阿里 Nacos(这些功能丰富但略笨重,如果仅有key-value需求可以自行简单实现)。

并发

高并发是一大棘手问题,解决它对于业务、编程方式、技术架构都是很大的考验。

  • 33. 打破时域耦合:理清工作流,分析哪些环节是并行执行的,从而提高并发
  • 34. 原子性:并发会引发不正确的共享状态,需要利用互斥锁等机制保持数据的原子性,如 MySQL 的行锁,Redis 分布式锁
  • 35. 协程:类似 Go 语言的 goroutine、channel 特性对于实现高并发有独到优势
  • 36. 消息队列:在满足高并发、解耦方面,消息队列是一大神器。开源的消息队列如 Kafka 等

当你编程时

编程不是简单地将设计翻译成代码的机械工作,是需要仔细思考和认真判断。如果想让程序长寿、运行准确高效,就要做一个积极思考的开发者,避免巧合式编程。

  • 37. 听从直觉:当面对一件事情时,有时会有一些难以表达的直觉,可能是关于不安、疑虑。先不要被直觉控制,仓促做出决定。可以给大脑一些自由的时间,让直觉中的想法渗透出来,然后抓住到。利用直觉找到问题,提高工作效率。
  • 38. 避免巧合式编程:深思熟虑的编程,需要有清晰的目标、熟练掌握使用的技术、按计划推进、依赖可靠的东西、将假设文档化的契约式设计、安排好优先级、不要被现有代码所限。
  • 39. 合理优化算法:不要过早地优化算法,在投入高贵的时间前先判断算法是不是真实瓶颈。这对于其他方面的优化也是一样。
  • 40. 重构:重组现有代码实体、改变其内部结构而不改变其外部行为的规范式技术。重构并不是全面重写,是一项日常工作。建议重构的原则是重构不要与添加功能同时进行,重构前先确保良好的测试,采取简短而慎重的步骤重构。
  • 41. 单元测试:单元测试是指对软件系统中的最小可测试单元进行检查和验证的一种测试方法。通常来说,最小可测试单元是指函数、过程或模块等。在进行单元测试时,测试人员会使用代码自动化工具或手工编写测试用例,对一个个独立的最小单元进行测试,并分析测试结果以确定其是否符合预期的要求。通过单元测试,可以尽早地发现并消除程序中的错误,从而提高软件质量,减少后期修复成本。如 PHPUnit
  • 42. 无
  • 43. 安全:安全性基本原则是1.将攻击面的面积最小化 2.最小特权原则 3.安全的默认值 4.敏感数据要加密 5.维护安全更新
  • 44. 命名:应用、模块、函数和变量等命名非常重要,它透露出你的意图和信念。如果名词不再能表达其意图或有误导性,请修改它。另外维护项目术语表,有助于准确简洁的表达很多含义。

项目启动之前

项目启动前,我们需要对需求有良好的理解与沟通(如 真实的需求文档),合适的团队合作方式(如 结对编程),恰当的项目管理方式(如 敏捷开发思想)。

  • 45. 需求:需求文档是为开发人员编写的,并不是客户(他理解不了)。需求不易太过具体,要真实反应客户需求,由开发人员思考抽象。维护一张项目术语表,有助于参与者保持一致性。
  • 46. 无法解决的难题:解决谜题的关键是,认识到你所受到的约束和你所拥有的自由度,因为认识到这些就会找到答案。开放思维,不要人为的给思考加上枷锁,让注意力分散或许更有用。
  • 47. 结对编程:两个程序员共同合作编写代码,一个人编写代码,另一个人观察和提出建议。鉴于人类大脑带宽有限,处理编程占用了人脑相当大的处理能力,另一个完整大脑,将提供更多脑力,有助于提高代码质量、加快开发进度并提高团队协作能力。
  • 48. 敏捷开发的本质:敏捷开发是一种思想,强调灵活性、适应性和快速响应变化。敏捷方式工作的秘诀是 1.弄清楚你在哪里。 2.朝想去的方向迈出有意义的最小一步。 3.评估在哪里终结,把弄坏的东西修好。重复这些步骤,直到完成。

务实的项目

一个务实可靠的团队才能成就一个优秀的项目

  • 49. 务实的团队:程序员聪明且固执,保持小(10-12人)而稳定的团队,彼此了解且信任。代码质量从来都是个团队问题,使用质量管把控代码质量没有意义,质量是内在的,需要团队每个成员去独立贡献,无法额外保证。团队的工作不仅仅是开发新功能,还包含旧系统维护、流程的反思与精炼、实验新技术、学习和提升技能等。赋予每个成员能力,让他们以自己的方式发光发热。要提供完善的架构来支持他们,并确保项目交付的价值。
  • 50. 实践检验:不要形式主义,盲从各类神器,要自己检验是否解决真实的问题。
  • 51. 务实的入门套件:版本控制、测试和自动化,有了这些运维套件,可以把精力集中在困难的部分:取悦用户
  • 52. 取悦用户:务实的程序员应该取悦用户,帮助他解决实际业务问题。
  • 53. 签名:为自己编写的代码签上自己大名,是一种引以为豪的质量认证。

未经作者允许,禁止转载。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇