关键思想
1. 代码应当易于理解
2. 代码的写法应当使别人理解它所需的时间最小化
3. 把信息装到名字里
4. 清晰和精确比装可爱好
5. 要多问自己几遍:“这个名字会被别人解读成其他的含义吗?”要仔细审视这个名字
6. 一致的风格比“正确”的风格更重要:感觉团队所用的风格是“错误的”,但是我们还是遵守项目的习惯,因为我们知道一致性要重要得多。
7. 注释的目的是尽量帮助读者了解得和作者一样多。
8. 不要为那些从代码本身就能快速推断的事实写注释
9. 注释应当有很高的信息/空间率
10. 把条件,循环以及其他对控制流的改变做的越”自然“越好,运用一种方式使读者不用停下来重复读你的代码
11. 相对于最求最小化代码行数,一个更好的度量方法是最小化人们理解它所需的时间
12. .当你对代码做改动时,从全新的角度审视它,把它作为一个整体来看待。
13. 把你的超长表达式拆分成更容易理解的小块
14. .要小心“智能”代码段——它们往往在以后会让别人读起来感到困惑
15. 让你的变量对尽可能少的代码行可见
16. 操作一个变量的地方越多,越难确定它的当前值
17. 应该把代码组织得一次只做一件事
18. 最好读的代码就是没有代码
19. 测试应当具有可读性,以便其他程序员可以舒适地改变和测试代码。
20. 当你选择一组最简单的输入时,他能完整的使用被测代码。
21. 与其建立单个“完美”输入来完整执行你的代码,不如多写个小测试,后者往往会更加容易,更有效并且更有可读性。
良句
一. 选择好的名字:把信息装到名字里
-
选择专业的词
send:deliver,dispatch,announce,distribute,route find:serach,extract,locate,recover start:launch,create,begin,open make:create,setup,build,generate,compose,add,new
-
找到更有表现力的词
-
避免像tmp,retval这样泛泛的名字
-
如果你要使用像tmp,it或者retval这样空泛的名字,那么你要有个好的理由
-
用具体的名字代替抽象的名字
-
把变量的命名也当作一个小的注释
-
带单位的值:如果你的变量是一个度量的话,那么最好把名字带上它的单位
-
附带其他重要属性:这种给名字附带额外信息的技巧不仅限与单位,在对于这个变量存在危险或者意外的任何时候你都该采用他
-
名字应该有多长?这是要你自己拿定主意的,最好的答案和这个变量如何使用有关系,但下面还有提出了一些指导原则
- 在小的作用域里可以用短的名字
- 首字母缩略词和缩写:是否使用取决于团队的新成员能否理解这个名字的含义
-
有目地地使用大小写,下划线等
二. 不会误解的名字
-
命名极限最清楚地方式是要在限制地东西前加上max_或者min_
-
推荐用first 和last表示包含的范围,不像stop,last这个名字明显是包含的
-
推荐使用begin和end来表示包含/排除范围
-
给布尔值命名:通常来讲,加上像is,has,can或should这样的词,可以把布尔值边得更为明确
-
与使用者的期望相匹配:有些名字之所以会让人误解是因为用户对它们的含义有先入为主的印象,就算你的本意并非如此
-
好的源代码应当“看上去养眼”,确切的说,有三条原则:
- 使用一致地布局,让读者很快就习惯这种风格
- 让相似的代码看上去相似
-
把相关的代码行分组,形成代码块
-
.重新安排换行来保持一致和紧凑
-
用方法来整理不规则的东西
-
在需要时使用列对齐,如果列对齐很费工夫,也可以不用做
-
选一个有意义的顺序,始终一致地使用它
- 让变量的顺序与对应的HTML表单中字段的顺序相匹配
- 从“最重要”到“最不重要”排序
- 按字母排序
-
把声明按块组织起来,把代码分成段落
三. 该写什么样的注释
-
写好的注释
-
把代码整洁地写成更好的格式
-
不要为了注释而注释
-
不要给不好的名字加注释——应该把名字改好:好代码>坏代码+好注释
-
加入“导演评论”:在代码中也加入注释来记录你对代码有价值的见解
-
为代码中的瑕疵写注释:不要不好意思把这些瑕疵记录下来
-
几种通用的标记:
-
给常量加注释:当定义常量时,通常在常量背后都有一个关于它是什么或者为什么它是这个值的“故事”
-
站在读者的角度:当别人读你的代码时,有些部分更可能让他们有这样的想法:”什么?为什么会这样?“你的工作就是要给这些部分加上注释。
-
公布可能的陷阱
-
让注释保持紧凑
-
精确的描述函数行为
-
用输入/输出例子来说明特别的情况
-
当像”it“和“this”这样的代词可能指代多个事务时,避免使用他们
-
声明代码的意图
-
采用信息含量高的词
四. 把控制流变得易度
-
if(length>=10)…
-
if/else语句块:
首先处理正逻辑而不是负逻辑。例如,使用if(debug)而不是if(!debug)
先处理掉简单的情况。这种方式可能还会使得if和else在屏幕之内都可见,这很好
先处理有趣的或是可以的情况
有时这些倾向性之间会有冲突,那么你就要自己判断了。但在很多情况下这都会有明确的选择 -
.默认情况下都使用if/else,三目运算符 ?:只有在最简单的情况下使用
-
避免do/while循环:do/while的奇怪之处是一个代码块是否会执行是由其后的一个条件决定的。通常来讲,逻辑条件应该出现在它们所“保护”的代码之前,这也是if,while和for语句的工作方式。
-
最小化嵌套,嵌套很深的代码很难以理解。
-
通过提早返回来减少嵌套
-
拆分表达式最简单的方法就是引入一个额外的变量,让它来表示一个小一点的子表达:这个额外的变量有时叫做“解释变量”,因为它可以帮助解释子表达式的含义
-
即使一个表达式不需要解释,把它装入一个新变量中仍然有用
这个写法比:
if(request.user.id==document.owner_id){…}else{…}好
五. 一次只做一件事
- 把巨大的表达式拆成小段
- 使用莫德根定律:
- not (a or b or c) <=> (not a) and (not b) and (not c)
- not (a and b and c ) <=> (not a) or (not b) or (not c)
- 布尔操作会做短路逻辑
- 从反方向解决问题
- 只写一次的变量更好:那些只设置一次值的变量使得代码更容易理解
- 创建大量通用代码,一般代码库中的的util目录
- 从你的项目中拆分出越多独立的库越好,因为你的代码的其他部分会更小而且更加容易思考
- 用自然语言来描述程序然后用这个描述来帮助你写出更自然的代码——这个技巧出人意料的简单,但是很强大,看到你在描述中所用的词和短语还可以帮助你发现哪些子问题可以拆分出来。这个过程不仅可以用于写代码。通过大声把问题描述出来,往往就能帮这个学生找到解决方法,这个技巧叫做「橡皮鸭技术」
- 另外看待这个问题的角度是:如果你不能把问题说明白或者用词语来做设计,估计是缺少了什么东西或者什么东西缺少定义。把一个问题(或想法)变成语言真的可以让它更具体。
- 知道什么时候不写代码对于一个程序员来讲是他所要学习的最重要的技巧。
ps:这句话深有含义,目前我还不能完全参悟,但至少现在我很想学习这样的技巧
- 你所写的每一行代码都是要测试和维护的。通过重用库或者减少功能,你可以节省时间并且让你的代码保持精简节约
- 程序员倾向于高估有多少功能真的对于他们的项目来讲是必不可少的;程序员还倾向于低估实现一个功能所要花的功夫。
ps:这个目前我没有太大的感受,反正就是看感觉吧,一般的都能解决,只要不太刁钻,能不能完成还是要看实现难度,当然随着经验和能力的增加,会用的工具越来越多,那么能实现的功能也会越来越多
- 需求常以微妙的方式互相影响,这意味着解决一半的问题可能是需要花四分之一的功夫
ps:maybe
- 删除没用的代码
- 熟悉你周边的库:每隔一段时间,花15分钟来熟悉
- 与其把我们主要的任务想象成指示计算机做什么,不如让我们关注解释给人类我们希望让计算机做什么。(p.99)——《Literate Programming》by Donald E.Kunth
观后感想
- 好名字也可以通过多看别人的命名学习,积累嘛~
- 代码的书写应该符合人类阅读习惯,很多细微的细节点作者都总结的很好,而且其实不用花太多时间,简单注意就能提升很多。
- 有些点确实要平常写的时候需要注意并养成习惯,觉得自己甚至有时候有点像写“产品说明书”一样,如果不能简单而明确的让使用者明白如何使用,那就是很失败,书中就介绍如何书写的方法。也不知道这个比喻是否正确。
- 某些points确实很棒,但在工作中,确实花时间了点,导致不太能去完成。赶排期和时间确实紧了点。
- 有时候一个逻辑会包含许多的情况,从反方向看,只要排除几种情况就完全解决,反方向解决问题的确是要经常用和反应出来。
- 以前觉得高级的代码就是一句话就能完成所有,函数调用里面嵌套调用,看完之后,觉得写代码其实和写一本说明书差不多了,有正常的业务流程,有处理逻辑等等等等。
- 自己觉得自己写的注释比较容易让人理解,但其实也不一定,每个人的理解方式是不一样的。
- 现在的我经验和年限都不长,有很多东西也还需要在以后慢慢斟酌,以上这些是我以后主要的指导方向。