《编写可读代码的艺术》
表面层次的改进
把信息塞入名字中
使用专业的单词
不用Get,而是用Fetch、Download
为作用域更大的名字采用更长的名字
首字母缩略词和缩写
BackEndManager 缩写成BEManager,这种方式不可取。
丢掉没用的词
convertToString,不如toString
三、不会误解的名字
filter会产生误解,是挑出来还是减掉。
推荐用min、max表示极限
CART_TOO_BIG_LIMIT = 10 if(shop_cart.num_items >= CART_TOO_BIG_LIMIT){ error }
建议改成
MAX_ITEMS_IN_CART = 10 if(shop_cart.num_items > MAX_ITEMS_IN_CART){ error }
表示开头和结尾,并且无包含的意思。建议用first、last代替start、stop
给布尔值命名
is、has、can、should可以让布尔值变得明确。
get 轻量级访问器,只返回一个内部成员变量
涉及相对复杂的操作,如计算
computeMean(),会比getMean()要好。
size通常用作表示,直接返回一个固定的大小
如果size涉及计算,使用countSize或countElements更合适。
审美
使用一致的布局
让相似的代码看上去相似
选择一个有意义的顺序,始终一致地使用它
关于变量排序:
- 从 最重要到最不重要排序
- 按字母排序
把声明按块组织起来
把代码分成段落
- 通过换行
- 通过注释
一致的风格,比正确的风格更重要
第5章 该写什么样的注释
注释的目的是尽量帮助读者了解得和作者一样多。
什么不需要注释
阅读注释会占用阅读真实代码的时间,并且每条注释都占屏幕的空间。所以注释最好物有所值。
代码本身就能快速推断的事实就不需要写注释了。
一个好的名字比一个好的注释更重要。
记录你的思想
在代码中加入注释,记录你对代码有价值的见解
为代码中的瑕疵写注释
例如
//TODO : 采用更快的算法
- TODO:还没有处理的事情
- FIXME:已知的无法运行的代码
- HACK:对一个问题不得不采用的比较粗糙的解决方案
-XXX:危险!这里有重要的问题
给常量加注释
- 注释解释这个常量值的效果
例如
NUM_THEADS = 8 //线程数最好是2的倍数 IMAGE_QUALITY=0.72 //使用0.72可以达到性能最优
站在读者的角度
通过注释来解答意料之中的疑问。
//这里因为什么原因,所以要用redis存储数据 redisUtils.put("xxx","xxx");
公布可能的陷阱
例如
//调用外部服务发送邮件(1分钟以后超时) void sendEmail();
全局观注释
文件级别的注释,可以解释一个模块的代码逻辑,可以减少团队成员理解整体代码的时间。
通过这种注释,可能你不需要对新同事将一遍代码逻辑,而是直接让他看简短的文件级别的注释即可。
可以做任何能帮助读者更容易理解代码的事情。
第6章 写出言简意赅的注释
注释应当有很高的信息/空间率
避免使用不明确的代词,如it,用具体的词代替,如data
//不同的优先级,取决于我们是否爬取
不如
//未爬取的网页给更高的优先级
用输入/输出例子来说明特别的情况。实例要选择具有代表性的,不要选模棱两可的。
如
//例子:Strip("abba/a/ba","ab") returns "/a/"
声明代码的意图
注释不要只停留在代码层面的意思,要从更高层次解释
//逆序遍历列表
不如
//展示所有价格,从高到低
采用信息量更高的词,缩减注释
简化循环和逻辑
第7章 把控制流变得易读
条件语句中参数的顺序
如
if(length >= 10)
要好于
if(10 <= length)
while(byte_recived < byte_expected)//更好 while(byte_expected > byte_received)
原则
比较的左侧:被问询的表达式,值更倾向于不断变化
比较的右侧:用来做比较的表示,更倾向于常量
if/else语句块的顺序
if(a==b){ //case one... }else{ //case two }
与
if(a !=b){ //case two }else{ //case one }
这两者孰优孰劣
原则:
优先处理正逻辑,而不是负逻辑。用if(debug)而不是if(!debug)
先处理简单的情况。
先处理有趣的或者可疑的情况。
这就好比有人说“不要去想一头粉红色的大象”,“不要“容易被”粉红色的大象“淹没。
当然如果负逻辑更简单、更有趣或更危险,可以先处理它。要根据具体情况来。
避免使用三目运算符,因为一个思想是:
相对于追求最小化代码行数,一个更好的度量方法,是最小化人们理解它所需的时间。
避免do/while循环
逻辑条件应该出现在它所保护的代码之前。
大多数的do、while都可以写成while循环。
while(){ if(xxxx){ break; } }
从函数提前返回,没有问题,而且常常很受欢迎
最小化嵌套
嵌套很深的代码,难以理解
if(user_result == SUCCESS){ if(permission_result != SUCCESS){ ... ... ... } }else{ .... }
上面的代码很不好。要如何改呢
可以通过提早返回来减少嵌套
if(user_result == SUCCESS){ return .. } if(permission_result != SUCCESS){ return .. } return ...
减少循环内的嵌套
for(int i = 0;i<result.size();i++){ if(...){ if(....){ .... } } }
可以使用continue来减少嵌套
for(int i = 0;i<result.size();i++){ if(result == null){ contitue; } if(....){ .... } }
你能理解执行的流程吗
不要在代码中使用 线程、信号量、异常的比例太高。容易让程序流程变得难读。
第八章 拆分超长的表达式
代码越长就越难理解。
用作解释的变量
如
if line.split(':')[0].strip() == "root": ...
不如替换成
username = line.split(':')[0].strip() if username == 'root'
总结变量
if(request.user.id == document.owner_id){ ... } if(request.user.id != document.owner_id){ ... }
将条件提取出来作为一个单独的变量
user_owns_document = request.user.id == document.owner_id
使用德摩根定理
(1) not( a or b or c) 等价于 (not a) and (not b) and (not c) (2)not (a and b and c) 等价于(not a) or (not b) or (not c)
例子
if(!(file_exists && !is_protected)) ...
改成
if(!file_exists || is_protected) ...
滥用短路逻辑,在很多逻辑中布尔操作都会做短路计算。
一个滥用的例子,相对让人难理解
asset((!(bucket = FindBucket(key))) || !bucket -> IsOccupied());
应改为
bucket = FindBucket(key); if(bucket != NULL) assert( !bucket -> IsOccupied())
与复杂的逻辑战斗
如果逻辑过于复杂,容易滋生Bug
- 《编写可读代码的艺术》---不会误解的名字
- 《编写可读代码的艺术》读后总结
- 《编写可读代码的艺术》---美观代码
- 《编写可读代码的艺术》读后总结
- 《编写可读代码的艺术》---该写什么样的注释
- 《编写可读代码的艺术》读书笔记
- 晒书有礼!《编写可读代码的艺术》(The Art of Readable Code)晒书有礼活动进行中
- 《编写可读代码的艺术》---写出言简意赅的注释
- 《编写可读代码的艺术》读书笔记
- 晒书有礼!《编写可读代码的艺术》(The Art of Readable Code)晒书有礼活动进行中
- 《编写可读代码的艺术》---把控制流变得可读
- 《编写可读代码的艺术》读书笔记(上)表面层次的改进
- 《编写可读代码的艺术》读书笔记
- 《编写可读代码的艺术》---拆分超长的表达式
- 《编写可读代码的艺术》读书笔记(下)简化循环和逻辑和重新组织代码
- 《编写可读代码的艺术》读书笔记02
- 《编写可读代码的艺术》---变量和可读性
- 阅读《编写可读代码的艺术》笔记
- 《编写可读代码的艺术》读书笔记03
- 读《编写可读代码的艺术》博客内容声明