首页 > 代码库 > 《编写可读代码的艺术》
《编写可读代码的艺术》
本书干货很多,许多确实可行的建议,是都是写好代码的必经之路,下面为我总结的导图和部分章节的概述。
很好的一本书,推荐给大家。
总结思维导图
第二章
本章唯一的主题是:把信息塞入名字中。这句话的含义是,读者仅通过读到名字就可以获得大量信息。
使用专业的单词————例如,不用Get,而用Fetch或者Download可能会更好,这由上下文决定。
避免空泛的名字,像tmp和retval,除非使用它们有特殊的理由。
使用具体的名字来更细致地描述食物————server can start()这个名字就比CanListenOnPort更不清楚
给变量名带上重要的细节————例如,在值为毫秒的变量后面加上_ms,或者在还需要转义的,为处理的变量前面加上raw_。
为作用域大的名字采用更长的名字————不要用让人费解的一个或两个字母的名字来命名在几屏之间都可见的变量。对于只存在于几行之间的变量用短一点的名字更好。
有目的地使用大小写、下划线等————例如,你可以在类成员和局部变量后面加上“_”来区分它们。
第三章
不会误解的名字是最好的名字————阅读你代码的人应该理解你的本意,并不会有其他的理解。遗憾的是,很多英语单词在用来编程时是多义性的,例如filter\length和limit。
在你决定使用一个名字之前,要吹毛求疵一点,来想象一下你的名字会被误解成什么。最好的名字是不会误解的。
当要定义一个ie值的上限或下限时,max_和min_是很好的前缀。对于包含的范围,first和last 是好的选择。对于包含/排除范围,begin和end是最好的选择,因为它们最常用。
当为布尔值命名时,使用is和has这样的词来明确表示它是个布尔值,避免使用反义的词。
要小心用户对特定词的期望。例如,用户会期望get(),或者size()是轻量的方法。
第四章
大家都愿意读有美感的代码。通过把代码用一致的、有意义的方式“格式化”,可以把代码变得更容易读,并且可以读得更快。
如果多个代码块做相似的事情,尝试让它们有同样的剪影。
把代码按“列”对齐可以让代码更容易浏览。
如果在一段代码中提到A、B和C,那么不要在另一段中说B、C和A。选择一个有意义的顺序,并始终用这样的顺序。
用空行来把大块代码分成逻辑上的“段落”
第五章
注释的目的是帮助读者了解作者在写代码时已经知道的那些事情。本章介绍了如何发现所有的并不那么明显的信息块并且把它们写下来。
什么地方不需要注释:
能从代码本身中迅速地推断的事实
用来粉饰烂代码(例如蹩脚的函数名)的“拐杖式注释”————应该把代码改好
你应该记录下来的想法包括:
对于为什么代码写成这样而不是那样的内在理由(“指导性批注”)。
代码中的缺陷,使用像TODO:或者XXX:这样的标记。
常量背后的故事,为什么是这个值。
站在读者的立场上思考:
预料到代码中哪些部分会让读者说:“啊?”并且给它们加上注释。
为普通读者意料之外的行为加上注释。
在文件/类的级别上使用“全局观”注释来解释所有的部分是如何一起工作的。
用注释来总结代码块,是读者不致迷失在细节中。
第六章
本章是关于如何把更多的信息装入更小空间里。下面是一些具体的提示:
当像“it”和“this”这样的代词可能指代多个事物时,避免使用它们呢。
尽量准确地描述函数的行为。
在注释中用精心挑选的输入/输出例子进行说明。
声明代码的高层次意图,而非明显的细节。
用嵌入的注释来解释难以理解的函数参数。
用含义丰富的词来使注释简洁
第七章
有几种方法可以让代码的控制流更易读
在写一个比较时(while(bytes_expected>bytes_received)),把改变的值写在左边并且把更稳定的值写在右边更好一些(while(bytes_received<bytes_expected))。
你也可以重新排列if/else语句中的语句块。通常来讲,先处理正确的/简单的/有趣的情况。有时这些准则会冲突,但是当不冲突时,这是要遵循的经验法则。
某些编程结构,像三目运算符、do/while循环,以及goto经常会导致代码的可读性变差。最好不要使用它们,因为总是有更整洁的代替方式。
嵌套的代码需要更加集中的精力去理解。每层新的嵌套都需要读者把更多的上下文“压入栈”。应该把它们改写成更加“线性”的代码来避免嵌套。
通常来讲提早返回可以减少嵌套并让代码整洁。“保护语句”(在函数顶部处理简单的情况时)尤其有用。
第八章
很难思考巨大的表达式。本章给出了几种拆分表达式的方法,以便读者可以一段一段地消化。
一个简单的技术是引入“解释变量”来代表较长的子表达式。这种方式有三个好处:
它把巨大的表达式拆分成小段
它通过用简单的名字描述子表达式来让代码文档化
它帮助读者识别代码中的主要概念
另一个技术是用德摩根定理来操作逻辑表达式——这个技术有时可以把布尔表达式用更简洁的方式重写(例如if(!(a&&!b))变成if(!a||b))。
本章给出了一个,把一个复杂的逻辑条件拆分成小的语句的例子。实际上,在本章所有改进过的实例代码中,所有的if语句内都没有超过两个值。这是理想情况。可能不是总能做到这样——有时需要把问题“反向”或者考虑目标的对立面。
最后,尽管本章是关于拆分独立的表达式的,同样,这些技术也常常应用于大的代码块。所以,你可以在任何见到复杂逻辑的地方大胆地去拆分它们。
第九章
本章是关于程序中的变量是如何快速累积而变得难以跟踪的。你可以通过减少变量的数量和让它们尽量“轻量级”来让代码更有可读性。具体有
减少变量,即那些妨碍的变量。我们给出了几个例子来演示如何通过立刻处理结果来消除“中间结果”变量。
减少每个变量的作用域,越小越好。把变量移到一个有最少代码可以看到它的地方。眼不见,心不烦。
只写一次的变量更好。那些只设置一次值的变量(或者const、final、常量)使得代码更容易理解。
第十章
对于本章一个简单的总结就是“把一般代码和项目专有的代码分开”。其结果是,大部分代码都是一般代码。通过建立一大组库和辅助函数来解决一般问题,剩下的只是让你的程序与众不同的核心部分。
这个技巧有帮助的原因是它使程序员关注小而定义良好的问题,这些问题已经同项目的其他部分脱离。其结果是,对于这些子问题的解决方案倾向于更加完整和正确。你也可以在以后重用它们。
第十一章
本章给出了一个组织代码的简单技巧:一次只做一件事情。
如果你有很难读的代码,尝试把它所做的所有任务列出来。其中一些任务可以很容易地变成单独的函数(或类)。其他的可以简单地成为一个函数中的逻辑“段落”。具体如何拆分这些任务没有它们已经分开这个事实那样重要。难的是要准确地描述你的程序所做的所有这些小事情。
第十二章
本章讨论了一个简单的技巧,用自然语言描述程序然后用这个描述来帮助你写出更自然的代码。这个技巧出人意料地简单,但很强大。看到你在描述中所用的词和短语还可以帮助你发现哪些子问题可以拆分出来。
但是这个“用自然语言说事情”的过程不仅可以用于写代码。例如,某个大学计算机实验室的规定声称当有学生需要别人帮它调试程序时,他首先要对房间角落的一只专用的泰迪熊解释他遇到的问题。令人惊讶的是,仅仅通过大声把问题描述出来,往往就能帮助这个学生找到解决的办法。这个技巧叫做“橡皮鸭技术”
另一个看待这个问题的角度是:如果你不能把问题说明或者用词语来做设计,估计是缺少了什么东西或者什么东西缺少了定义。把一个问题(或想法)变成语言真的可以让它更具体。
第十三章
冒险、兴奋——绝地武士追求的并不是这些——尤达大师
本章是关于写越少代码越好的。每行新代码都需要测试、写文档和维护。另外,代码库中的代码越多,它就越“重”,而且在其上开发就越难。
你可以通过以下方法避免编写新代码:
从项目中消除不必要的功能,不要过度设计。
重新考虑需求,解决版本最简单的问题,只要能完成工作就行。
经常性地通读标准库的整个API,保持对它们的熟悉程度。
第十四章
在测试代码中,可读性仍然很重要。如果测试的可读性很好,其结果是它们也会变得很容易写,因此大家会写更多的测试。并且,如果你把事实代码设计得容易测试,代码的整个设计会变得更好。
以下是如何改进测试的几个具体要点:
每个测试的最高一层应该越简明越好。最好每个测试的输入/输出可以用一行代码来描述。
如果测试失败了,它所发出的错误消息应该能让你容易跟踪并修正这个bug
使用最简单的并且能够完整运用代码的测试输入。
给测试函数取一个有完整描述性的名字,以使每个测试所测到的东西很明确。不要用Test1(),而用像Test_<FunctionName>-<Situation>这样的名字。
最重要的是,要使它易于改动和增加新的测试。
关于写高质量代码的书
《Code Complete:A Practical Handbook of Software Constructionm,2nd edition》,by Steve McConnell
一本严谨的大部头,是关于软件建构的所有方面的,包括代码质量以及其他。
《Refactoring:Improving the Design of Existing Code》,by Martin Fowler et al.
一本关于增量代码改进哲学的好书,包含很多不同重构方法的具体分类,以及要在尽量不破坏东西的情况下做出这些改动所需的步骤。
《The Practice of Programming》,by Brain kernighan and Rob Pike
讨论了编程的很多方面,包含调试、测试、可移植性和性能,有很多代码示例。
《The Pragmatic Programmer:From Journeyman to Master》,by Andrew Hunt and David Thomas
一系列好的编程和工程原则,按短小的讨论来组织。
《Clean Code:A Handbook of Agile Software Craftmanship》,by Robert C.Martin
和本书类似(但是专门为Java),还拓展了其他如错误处理和并发等话题。
关于各种编程话题的书
《JavaScript:The Good Parts》,by Douglas Crockford
我们认为这本书的精神与我们的书相似,尽管该书不是直接关于可读性的。它是关于如何使用JavaScript语言中不容易出错而且更容易理解的一个清晰子集的。
《Effective Java,2nd edition》,by Joshua Block
一个杰出的书,是关于让你的Java程序更易读和更少bug的。尽管它是关于Java的,但其中很多原则对所有的语言都适用。强烈推荐。
《Design Patterns:Elements of Reusable Object-Oriented Software》,by Erich Gamma,Richard Helm,Ralph Johnson,and jon Vlissides
这本书是软件工程师用来讨论面向对编程所用的“模式”这种通用语言的原始出处。作为通用的、有用的模式的一览,它帮助程序员在第一次自己解决棘手问题时避免经常出现的陷阱。
《Programming Pearls,2nd edition》by Jon Beentley
关于真实软件问题的一系列文章。每一章都有解决真实世界中问题的真知灼见。
《High Performance Web Sites》,by Steve Souders
尽管这不是一本关于编程的书,但这本书也值得注意,因为它描述了几种不需要写很多代码就可优化网站的方法
《Joel on Software:And on Diverse and ...》,by Joel Spolsky
来自与http://www.joelonsoftware.com/的一些优秀文章。Spolsky的作品涉及软件工程的很多方面,并且对很多相关话题都深有见解。一定要读一读“Things You should Never Do,Part I”和"The Joel Test:12 Steps To Better code"
《编写可读代码的艺术》