《Pragmatic Programmer》
豆瓣地址
这本书的中文版被翻译为《程序员修炼之道——从小工到专家》,看起来有点中二,其实原名直译《注重实效的程序员》就很合适了。
定位于给初级开发人员阅读,涉及到软件工程开发的方方面面,摒弃平时所关注的语言特性,技术细节,而是高屋建瓴,着眼于正确的软件设计方法和应该具备的软件工程意识。(也是一个机会了解行业术语与典故)
一、工程意识
① Don't Live with Broken Windows: 不要容忍破窗户
这其实就是所说的“破窗理论”,破窗户(低劣的设计,糟糕的代码,临时凑合出的可以 work 的奇怪 hack function)具有传染性,只会导致项目中破窗户越来越多,一堆临时的 hack 修补引起连环问题,直到难以修复,程序崩溃。
熵增定律告诉我们,一个封闭系统总是趋向于熵增,也就是系统的无序程度只会不断增加。软件开发中也是如此,不要容忍破窗户,尽快修复任何已察觉到的问题。
② DRY - Don't Repeat Yourself 不要重复你自己
Make It Easy to Reuse 让复用变得容易
There Are No Final Decisions 不存在最终决策
也是非常有名的 DRY
原则,与在《重构》与《设计模式》中学习到的类似,应使得我们的程序更
介绍了几种可能出现重复的场景,应使得程序具有正交性,不仅出于好维护的目的,也为了避免由于需求变更而扩展性不够导致需要重写。(从这里看来软件开发的常见问题这么多年都没啥变化)
要警惕自己出于懒惰而做的 Copy&Paste,它不仅对项目没什么好处,也是一种“恶劣习惯”的开始。
维持代码正交性的方法(其实也是重构原则):
- 让你的代码保持解耦:
Law of Demeter
- 避免使用全局数据
- 避免编写相似的函数:可以通过策略模式实现
③ Estimate to Avoid Superises: 估算,以避免发生意外
Iterate the Schedule with the Code: 通过代码对进度表进行迭代
书中提到“使用的时间单位会对结果的解读造成影响”,并由此提到了相应的建议估算单位,这个还是很有意思的:
这只算一些估算经验,真正想进行准确有效的估算,还是要不断复盘检测,建立自己的系统模型,组织开发中所用的步骤,进行合理的模块划分来估算项目进度。
④ Keep Knowledge in Plain Text: 用纯文本保存知识
Configure, Don't Integrate: 要配置,不要集成
Put Abstractions in Code, Details in Metdata: 将抽象放进代码,细节放进元数据
这里提到了使耦合减少至最少的一个方法,使用 Metadata
元数据,让我们的系统变得高度可配置。元数据是关于数据的数据,比如说数据库 schema
,对字段进行描述。
通过以声明方式思考,由元数据驱动的应用将迫使我们解除设计耦合,推迟细节处理并大大提到了可复用性,能快速响应由需求变更导致的改动。
⑤ Don't Program by Coincidence 不要靠巧合编程
这是一个很简单也显而易见的事,然而还是会经常出现“好不容易跑起来了,哪都不要动,先这样吧”。不仅如此,很多时候也是会不经意地忽略这件事,需要警惕,此时能实现很可能是由于正处于边界条件,只是偶然。
因此不仅要用 case 测试我们的代码,还要对测试 case 进行深思,通过一些覆盖不全、偶然情况的 case 并不意味着代码是 OK 的。
二、开始实际的开发
① Estimate the Order of Your Algorithms 算法速率
书中也简单介绍了 大O表示法
与一些常见算法的复杂度。在这里要牢记,要根据实际情况做出选择,过度追求算法上的优化而增加了测试维护的成本得不偿失。
② Don't Gather Requirement - Dig for Them 不要搜集需求——挖掘它们
Abstractions Live Longer than Details 抽象比细节活得更长久
要对需求敏感,不假思索完全按照 PM 提过来的需求描述进行开发,可能会导致项目中的代码扩展性不好。举个例子,“只有人事部门可以查看档案”与“只有指定人员才能查看员工档案”这就是两个不一样的概念。完全按照前者来开发,很有可能只是将人事部门的组织id写入代码,而后者意味着我们可能需要做一个权限服务而与业务逻辑分离。
因此,应该 把政策的文档与需求的文档分开,使需求称为一般陈述,并把政策信息作为例子发给开发者,作为在具体视线中需要支持的一个 Case,最后政策可以称为应用中的元数据。
找出用户为何要做特定事情的起因
,而不只是他们目前做这件事的方式
。因为作为开发者是要解决用户的商业问题,而不只是满足用户陈述的需求,解决需求的方式是很有可能发生变化的,而深入挖掘到要解决的根本问题,才是可以使得系统高效,开发人员也不必为需求疲于奔命的解决方式。
在编写我们开发人员自己使用、查阅的需求文档时,应注重保持抽象
,在涉及需求的地方,最简单的,能够准确地反映商业需要的陈述才是最好的,必须把底层的语义不变项
当做需求进行捕捉。如上个例子,控制可以查看档案的权限,即是语义不变项。
③ Listen to Nagging Doubts -Start When You're Ready 等你准备好再开始
这里讨论了“启动恐惧症”,这件事我也经常遇到,但是并没有反思在什么情况下会出现启动恐惧症,每次都是拖延许久最后在无限抵触和焦虑中把项目赶完了。
书中提出应该注意到自己的疑虑,在长时间的积累后,我们的直觉也会很有用处。除此之外,如果我们发现这种疑虑只是出于拖延的话,应该 选择一个你觉得会有困难的地方,开始进行某种“概念验证”,这样可以有效快速地使启动起来了,因为行动结果无非有两种,一种是我们发现,这个困难可以解决然后就可以消除疑虑正式投入开发,另一种我们发现这个地方确实有问题,然后通过求助外界或者更改需求来推进它,总之项目是有了一个不小的进展。
上述只是记了一些我在阅读中感触比较多的地方,实际上这本书虽然是一个蛮远久的“名著”,其中概念都很经典并不过时,书中每页都有启示。还是希望我在实习期就有机会看到这本书的,现在开始也并不晚,并且应该多回顾,随着开发经验的增多应该收获也会越来越多。