Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
title: 1 | ||
layout: post | ||
guid: urn:uuid:dc6c0902-3f43-4f69-b493-1a865bd869ac | ||
tags: | ||
- | ||
--- | ||
|
||
|
176 changes: 176 additions & 0 deletions
176
_posts/2013-05-21-the-art-of-readable-code-s-note.markdown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
--- | ||
title: 编写可读代码的艺术读书笔记 | ||
layout: post | ||
guid: urn:uuid:5f5801a5-3229-4f37-8af0-b6aa12831a4a | ||
tags: | ||
- | ||
--- | ||
|
||
编写可读性强的代码的关键思想是:**代码应该易于理解**,关键原则是**应该让别人理解它的时间最小化** | ||
|
||
选择专业的词 | ||
------- | ||
|
||
避免空洞的词,如getSize(),getPage(),选择如getSquare(),getDownloadPage() | ||
|
||
找到更有表现力的词 | ||
------------------ | ||
|
||
如send -> deliver,dispatch,announce,distribute,route | ||
|
||
避免tmp和retval这样泛泛的词 | ||
--------------------------- | ||
|
||
* tmp只应用于短期存在且临时性为其存在因素的变量 | ||
* retval 应该用更有意义的变量名替代,如sum,square | ||
|
||
|
||
循环迭代器 | ||
-------------- | ||
|
||
在有多重循环时,可能会使用i,j这样的方式,但是根据要迭代的对象的数组如username来命名迭代变量为ui,uj更容易让人理解。 | ||
|
||
用具体的名字代替抽象的名字 | ||
------------------------- | ||
|
||
在给变量,函数或者其他元素命名时,要具体而不抽象。 | ||
|
||
* 给单位变量命名时可以加上单位,如delay\_sec | ||
* 加上附属信息,如plaintext\_password,html\_utf8 | ||
|
||
小作用域中可以使用短名字 | ||
----------------------- | ||
|
||
使用项目特有的缩写词非常糟糕,难以理解,如BE->backend | ||
|
||
|
||
根据名字格式来传递含义 | ||
----------------------- | ||
|
||
使用特定的名字格式约定能够方便代码阅读 | ||
|
||
避免会误解的名字 | ||
--------------- | ||
|
||
如filter,clip这些二意的词语 | ||
|
||
使用min和max来表示极限,first和last来表示包含的范围,begin和end来表示包含和排除的范围 | ||
|
||
|
||
布尔值 | ||
--------------------------- | ||
要确保返回true或者false的意义明确,如read\_passwd无法确定是要去读取还是已经读取 | ||
|
||
避免使用反义的名字,如不要用disable\_ssl而使用use\_ssl | ||
|
||
|
||
与使用者期望相同 | ||
--------------------------- | ||
get,size等方法大家第一印象是O(1)时间复杂度的 | ||
|
||
美感的代码 | ||
--------------------------- | ||
使用一致化的,有意义的格式将代码格式化,可以将代码变得更为易懂 | ||
|
||
* 如果多个代码块做类似的事情,让他们一致 | ||
* 让代码按列对齐可以让代码更容易浏览 | ||
* 如果在一段代码以特定顺序提到A,B,C,则在另一端代码中不要以C,B,A出现,要一直按某一个有意义的顺序出现,重要的放在最前 | ||
* 可以用空行来把大段的代码分成逻辑上的段落 | ||
|
||
|
||
注释代码 | ||
--------------------------- | ||
注释的目的是帮助读者了解作者在写代码时已经知道的事情, | ||
|
||
什么地方不需要注释 | ||
* 能从代码中很快地推断事实。 | ||
* 用来粉饰烂代码---应该把代码改好 | ||
|
||
应该记录下来的想法包括 | ||
|
||
* 对于为什么代码写成这样而不是其他的内在理由(指导性批注) | ||
* 代码中的缺陷,使用像TODO:或者XXX:这样的标记 | ||
* 常量背后的故事,为什么是这个值 | ||
|
||
站在读者的立场上思考: | ||
* 预料到代码中哪些部分会让读者说:“啊?”并且给他们加上注释 | ||
* 为普通读者意外之外的行为加上注释 | ||
* 在文件/类的级别上使用“全局观”来注释所有的部分是怎么样工作的 | ||
* 用注释来总结代码块,使读者不致迷失在细节中 | ||
|
||
写注释的艺术 | ||
--------------------------- | ||
一定要言简意赅 | ||
|
||
* 出现it之类的代词时,使用具体事物表示 | ||
* 尽量精确地描述函数的行为 | ||
* 在注释中使用精心挑选的输入/输出例子进行说明 | ||
* 声明代码的高层次意图,而非明显的细节 | ||
* 用嵌入的注入如Func(\\*arg=*\\...)来解释难以理解的函数参数 | ||
* 使用含义丰富的词来使注释简洁。 | ||
|
||
代码的控制流程 | ||
--------------------------- | ||
|
||
在写if比较时,常量或更稳定的值放右边,变量放左边 | ||
|
||
if/else 先处理正确的,简单的,有趣的 | ||
|
||
三木运算符,do/while,goto会导致可读性降低,应该尽量避免,但是适当情况也可以采用 | ||
|
||
嵌套的代码应该改成线性的代码,避免深嵌套:可以提前返回return,通常在函数顶部处理简单的情况,或者可以采用continue跳出当前循环。 | ||
|
||
|
||
拆分表达式 | ||
--------------------------- | ||
使用解释变量来代表较长的子表达式,好处 | ||
* 可以把巨大的表达式拆成小段 | ||
* 通过简单的名字描述子表达式让代码文档化 | ||
* 帮助读者识别代码中的主要概念 | ||
|
||
使用德摩根定理来操作逻辑表达式,把if(!(a&&!b))写成if(!a||b) | ||
|
||
|
||
变量与可读性 | ||
--------------------------- | ||
|
||
通过减少变量的数量和尽量使变量轻量级 | ||
|
||
具体有 | ||
* *减少变量* 去除没有价值的临时变量,减少控制流变量, | ||
* 减少变量的作用于,如可以在if语句中声明和使用变量,if(a=func()) | ||
* 只写一次的变量更好,如const,常量等等 | ||
|
||
|
||
抽取不相关子问题 | ||
--------------------------- | ||
把一般代码和项目专有的代码分开。大部分代码是一般代码,简历一大组库和辅助函数来解决一般问题 | ||
|
||
组织代码的技巧 | ||
--------------------------- | ||
一次只做一件事情,一些可以变为单独的函数,另外一些可以变为函数中的段落,可以用空行fenge | ||
|
||
把想法变成代码 | ||
--------------------------- | ||
用自然语言描述程序,然后用这个描述来帮助你写出更自然的代码 | ||
|
||
少写代码 | ||
--------------------------- | ||
让你的代码库越小,越轻量级越好 | ||
|
||
办法 | ||
* 创建越多越好的“工具”代码来减少重复代码 | ||
* 减少无用代码或没有用的功能 | ||
* 让你的项目保持分开的子项目的方法 | ||
* 要小心代码的“重复”。 | ||
|
||
熟悉所使用的语言的标准库的API,保持对他们的熟悉程序 | ||
|
||
测试与可读性 | ||
--------------------------- | ||
测试应当具有可读性,让其他程序猿可以舒服地改变或者增加测试 | ||
|
||
* 每个测试的最高一层应该越简明越好。最好每个测试的输入或者输出可以用一行代码来描述 | ||
* 错误信息容易跟踪 | ||
* 使用最简单的并且能够完整运用代码的测试输入 | ||
* 给测试函数取一个完整描述性的名字,以使每个测试所测到的东西都很明确。如Test\_functionname\_situation |