时间:2021-07-01 10:21:17 帮助过:10人阅读
本书旨在帮助你把代码写的更好
代码的写法应当使别人理解它所需要的时间最小化
把理解代码所需的时间最小化是一个更好的目标
根本不会相互影响
经常想其他人是否会觉得你的代码容易理解,需要额外的时间
选择好的名字、写好的注释以及把代码整洁地写成更好的格式
术语上区分它的职能、找到更有表现力的词
好的名字应当描述变量的目的或者它所承载的值
如果你需要使用像tmp、lt或者retval这样空泛的名字,那么你要有个好的理由
在给变量、函数或者其他元素命名时,要把它描述的更具体而不是更抽象
如果关于一个变量有什么重要事情要读者必学知道,那么是值得把额外的“词”添加到名字中的。
带单位的值、附加其他重要属性
名字不能太长
在小的作用域里可以使用短的名字
输入长名字————不再是个问题(编辑器的“单词补全”功能)
首字母缩略词和缩写
丢掉没用的词
驼峰类名、下划线方法名、常量驼峰加kConstant前缀、宏是全大写下划线分词、构造函数首字母大写、jQuery对象前加$
有目的地使用大小写、下划线等
要多问自己几遍:“这个名字会被别人解读成其他的含义吗?”
二义性词,不知道其含义是“挑出”还是“减掉”
二义性词,可能是从尾部删除,也可能时裁掉最大长度为length的一段
命名极限最清楚的方式是在要限制的东西前加上max或者min。
当为布尔变量或者返回布尔值的函数选择名字时,要确保返回true和false的意义很明确。
最好避免使用反义名字。如'disable_ssl'。
有些名字之所以会让人误解是因为用户对它们的含义有先入为主的印象,就算你的本意并非如此。在这种情况下,最好放弃这个名字而改用一个不会让人误解的名字。
分析每个备选名字,考虑各种让人误解的可能性。
让代码变得更易读有三条原则:
. 使用一致的布局,让读者很快就习惯这种风格. 让相似的代码看上去相似. 把相关的代码行分组,形成代码块
让人愉悦的代码更容易阅读
使代码“看上去漂亮”通常会带来不限于表面层次的改进,它可能会帮你把代码的结构做的更好。
有一大堆get参数要获取,我们对代码中每个获取的顺序有一些想法:
. 让变量的顺序与对应的HTML表单中字段的顺序相匹配. 从“最重要”到“最不重要”. 按字母顺序排序
注释的目的是尽量帮助读者了解得和作者一样多
不要为那些从代码本身就能快速推断的事实写注释
不要为了注释而注释
不要给不好的名字加注释————应该把名字改好
写代码时有过重要想法
想象你的代码对于外人来讲看起来是什么样子的
公布可能的陷阱
全局观注释,考虑到新人加入,让她熟悉代码库
注释应当有很高的信息/空间率
如it、this
Return the number of lines in this file和Count how many newline bytes('\n') are in the file
Example
What you want do
默认参数 Connetc(timeout = 10, user_encryption = false)
做不到,用Connet(/* timeout_ms= */ 10, /* use_encryption = */ false)
如果你感觉到一段注释太长了,那么可以看看是不是可以用一个典型的编程场景来描述它
试着最小化代码中的“思维包袱”
把条件、循环以及其他对控制流的改变做得越“自然”越好。运用一种方式使读者不用停下来重读你的代码
比较的左侧比较的右侧“被问询的”表达式,它更倾向于不断变化的用来做比较的的表达式,它的值更倾向于常量
. 首先处理正逻辑而不是负逻辑的情况。例如,用if(debug)而不是if(!debug)。. 先处理掉简单的情况。这种方式可能还会使if和else在屏幕之内都可见. 先处理有趣的或者是可疑的情况
相对于追求最小化代码行数,一个更好的度量方法是最小化人们理解它所需的时间。
默认情况下使用if/else。三目运算符?:只有在最简单的情况下使用
我的经验是,do语句是错误和困惑的来源……我倾向于把条件放在“前面我能看到的地方”。其结果是,我倾向避免使用do语句。
应该避免使用goto
嵌套很深的代码很难以理解
当你对代码做改动时,从全新的角度审视它,把它作为一个整体来看待
通过提早返回来减少嵌套
不要让代码中使用“线程”、“信号量”、“异常”、“函数指针和匿名函数”、“虚方法”过多让实现流程变的高级难懂。
把你的超长表达式拆分成更容易理解的小块
临时中间变量
分别取反,转换与/或
要小心“智能”的小代码————它们往往以后会让别人读起来感到困惑。
struct Range{ int begin; int end; //For example,[0,5) overlaps with [3,8) bool OverlapsWith(Range other);}
相反比较
bool Range::OverlapsWith(Range other){ if(other.end <= begin) return false; if(other.begin >= end) return false; return true;}
提取公用部分放入函数作为总结变量
定义宏
变量越多,就越难全部跟踪它们的动向
变量的作用域越大,就更需要 跟踪它的动向越久
变量改变得越频繁,就越难以跟踪它的当前值
没有价值的临时变量
减少中间结果
减少控制流变量
让你的变量对尽量少的代码行可见。
操作一个变量的地方越多,越难确定它的当前值。
函数级别对代码做的更大的改动
看看某个函数或者代码块,问问自己:这段代码高层次的目标是什么?
对于每一行代码,问一下:它是直接为了目标而工作吗?这段代码高层次的目标是什么呢?
如果足够的函数在解决不相关的子问题,抽取代码到独立的函数中。
把一般代码和项目专有的代码分开
子代码自称一体后改进它变得更容易
通用代码很好,因为“它完全地从项目的其他部分中解耦出来”
你永远都不要安于使用不理想的接口
别分的太细,多个小函数对可读性不利
应把代码组织得一次制作一件事情。
投票的例子
如果你不能把一件事情解释给你祖母听的话说明你还没有真正理解它。
用自然语言描述逻辑
编写精炼代码的一部分工作是了解你的库提供了什么。
自然语言描述逻辑、适当递归调用自身
最好读的代码就是没有代码
让你的代码库越小,越轻量级越好
删除没用的代码
每隔一段时间,花15分钟阅读标准库中的所有函数/模块/类型的名字
成熟的库中,每行代码都代表大量的设计、调试、重写、文档、优化和测试。
通过以下方法避免编写新代码:
. 从项目中消除不必要的功能,不要过度设计。
. 重新考虑需求,解决版本最简单的问题,只要能完成工作就行。
. 经常性地通读标准库的整个API,保持对它们的熟悉程度。
测试应当具有可读性,以便其他程序员可以舒服地改变或者增加测试
使这个测试更可读
对使用者隐去不重要的细节,以便更重要的细节会更突出
创建最小的测试声明
大多数测试的基本内容都能精炼成“对于这样的输入/输出情形,期望有这样的行为/输出”
实现定制的“微语言”
了解显示错误的库
手工打造错误消息
错误消息应当越有帮助越好
基本原则是,你应当选择一组最简单的输入,它能完整地使用被测代码
又简单又能完成工作的测试值更好
一个功能的多个测试
Test_
你会开始把代码写得容易测试!
. 牺牲真实代码的可读性,只是为了使能测试. 着迷于100%的测试覆盖率. 让测试成为产品开发的阻碍
跟踪过去一分钟和一个小时里Web服务器传输了多少字节。