书名的意义

一般来说名叫大全的书,都是包含方方面面的知识,或者是所有的相关全部的范例。《代码大全》显然不可能是所有代码的范例,所以理解来看,就应该是关于代码方方面面的知识。如果看到本书的英文原名 《Code Complete》可能会更加理解一点。从中文翻译来看其实是有点吃亏的,看到大全类的书一般会觉得比较浅显或者言过其实,但是本书看完之后,觉得真是有关写代码的大而全的知识。

本书讲了什么

当前阅读的这本是第一版,成书时间较早,在 1993 年,书中使用的演示语言,很多是 basic ,pascal,以及少量的 c ,其实现在看来有点过时,不过串起内容来看,还真是经典永不过时。

本书从软件构建的步骤开始,从问题定义,需求分析等开始,到结构设计,以及选择语言,创建程序开始,详细讲解了各种程序设计中的原则和实践方案。在程序设计过程中如何保持高效的编码与尽量少的查错,然后关于文档,评审,测试,调试等手段都有涉及,涉及的各个方面还不是简单的一带而过。每个板块说明后面都附上了一个“检查表”,可以说,仅仅按照这个“检查表”进行实践,就可以避免编程过程中的大量错误。

本书的一些指导性意见,并不是干巴巴的说教,很多方面都有对应的研究和论文,数据支撑。可以不夸张的说,本书是在以写论文的方式来研究写代码。相比来说,很多讲编程技巧或者方案的书籍,一般都是举一些例子来说明自己的观点,有时候脱离了对应的语境,例子所表达的方法可能不是那么准确,让人在实践时候感到无从下手。阅读本书不会有这样的感觉。

精彩摘抄

编程中最富于挑战性的 问题便是将问题概念化,编程中许多错误往往都是概念性错误,因为每个程序在概念上都是独 特的,所以创立一套可以指导每一个问题的规则是非常困难,甚至是不可能的。

所谓“没有银色子弹”。

不要把最新的“面向对象设计技术”当作上帝赐予的法宝,它不过是一件在某些场合下有用, 而在某些场合下又无用的技术。

一直觉得“面向对象”被夸大了,近年来一些语言例如 go,rust 等没有传统的面向对象那些对象,继承等概念,也获得了很大的成功,表明其实还有其他行之有效的方案。当然在成书的90年代能有这样的见解是非常难得的。

测试既不能消除在正确方向上的错误工作,也不能消除在错误方向上的正 确工作的错误,这种错误必须在测试开始之前就清除掉,甚至在创建工作开始之前就要努力清 除掉它们。

软件设计正确才是硬道理,思维不清,靠测试是很难做好实际的编程工作的。

程序员也可能同样受到他所懂得的程序语言限制。在某种程序语言方面你所懂得的词汇, 当然会决定你如何表达你的编程想法,还很可能决定你将表达什么样的思想。

有些编程技术/范式是和语言强相关的,比如 c 的就注定不会有 lisp 那种灵活性。所以有些核心编程思想是和语言相关的,面对问题,有时候需要选择最合适的语言。

如果在给程序找一个好名字时感到困难,这往往意味着对程序的功能还不十分 清楚。

名字一般被划分在“编程风格”的范围,但是从逻辑上讲,一段程序要做的事情应该是清晰的,既然是清晰的,那一定会有一个恰当的名字,而不是是什么abcd。很多优秀的代码,命名也是非常恰当和流畅的。有时候光看命名就能大概直到一个程序员的水平。

优化的收益主要 来自高层次设计,而不是个别子程序、只有在高层次设计某方面有缺陷时,才需要进行微观优 化,而这点只在程序全部完成时才会知道。除非必要,不要浪费时间进行增量改进。

过早优化是万恶之源!

本书的重点之一,就是想告诉读者如何避免陷入把各种代码拼凑到一起,通过试运行检验 它是否有效的怪圈。而在确信程序是正确的之前,就匆忙开始编译,恰恰是陷入了这种怪圈。 如果你还没有进入这个怪圈,那最好还是当确信程序正确之后再开始编译。

做正确的事情,就是正确的做事。

把简单操作放入函数的另外一个原因:简单操作往往倾向于变成复杂操作。

如果有异常处理或新情况,那么之前本来很简单的语句,可能会变成复杂,这时候之前抽象出来的函数就有意义了

建立具有内部整体性(强内聚性),而同时与其它子程序之间的联系的直接、可见、 松散和灵活的子程序(松散耦合)

高内聚,低耦合是程序设计的基本原则。

一个好的程序从来不会输出乱七八糟像垃圾似的东西,不管它被输入的是什么。

其实很考察能力,有个说法是用户不会按照程序员设想的方式来使用程序,但是往往这些细节才是一个程序比其他程序优秀的点所在。

面向对象设计主要是设计模块数据和对数据操作的集合。它非常适于从最顶层分解系统。 而当你识别出对象的接口并开始编码时,你往往会转向结构化设计。

有时候遇到一些不那么“面向对象”的过程,其实本质上这种抽象就不一定是现实情况。

设计是一个复杂的过程。…说它是 一个复杂的过程也是因为你不知道什么时候设计方案已经足够完善了。什么时候算完成呢?对 这个问题的通常答案是“当你没有时间时”。

先解决问题,再优化,如果一直设计,可能都无法解决问题。

如果在编写一个先进系统时,不得不借用许多旧的、设计得不好的代码,那么你可以在新 系统中建立一个层(layer),与那些旧代码相联接。

计算机领域的法宝,就是建立一个中间层,如果一个无法解决问题,就再建立一个。

在编程中,最大的错误原因之一便是对数据不恰当的初始化。开发有效地避免初始化错误 的技术,可以节约大量的调试时间。

经验之谈!

管理回归测试的唯一可行方法是使回归测试自动化。当人们将相同的测试进行许多次并看 到许多次的结果都相同时;他们会对此厌烦,这会导致人们非常容易忽视错误,使回归测试目的破产。

超级经验之谈!

软件计划是变化:代码在变化、设计在变化、需求在变化,而且需求的变化引起设计上更 多的变化,设计上的变化又会引起代码和测试情况的更多变化。

所以开发不容易。。。

检查是一种特殊类型的评审,它在错误检查中被证明是行之有效的,并且和测试相比,它 是一种相对较为经济的办法。

检查和评审在去除bug,提升代码质量方面比想象中的作用更大。

总结

本书中精彩的论述还有很多,没办法一一列举。其实本书是一本工具书,针对编码的每个方面,都有一些对应的描述和行之有效的方法,因此完全可以放在手头,等到使用的时候详细翻阅。