读《编写可读代码的艺术》

《编写可读代码的艺术》是与Clean Code相似的书,提供改善“丑陋”代码的技巧。本书193页,共16章内容。


图书封面

本书分为四个部分:

  • 表面层次的改进-命名/注释以及审美
  • 简化循环和逻辑
  • 重新组织代码
  • 精选话题

关键思想:代码应当易于理解

可读性基本定律:代码的写法应当使别人理解他所需的时间最小化。

1 表面层次的改进

包括好的名字,好的注释,还有好的格式

1.1 把信息装进名字里

1.1.1 选择专业的词

反例: 函数名 GetPage(url)
正例: FetchPage()、DownloadPage()
反例: class BinaryTree的方法Size() VS
正例:Hight() NumberNodes(),MemoryBytes()
反例: class Thread的方法Stop()
正例: Kill() Pause(),Resume()

1.1.2 避免泛泛的名字

关键思想:清新和准确比装可爱好
迭代器变量,应该有明确指向

选择更有表现力的词

避免tmp和retcode泛泛的名字
retcode建议:retcode没有包含更新信息。描述该变量的值的名字代替它。

retcode改为sum_squares

tmp建议:tmp这个名字只应用于短期存在且临时性为其主要存在因素的变量。
tmp改为user_info

如果需要使用tmp,也需要指明tmp_file,或者tmp_data.
迭代器变量,应该有明确指向
i,j,k改为clubls_i/ci,members_i/mi,users_i/ui

1.1.3 用具体的名字代替抽象的名字

名字更具体而不是抽象

反例: 函数ServerCanStart:检测服务是否可以监听某个端口
正例: CanListenOnPort()
DISALLOW_COPY_AND_ASSIGN更好

1.1.4 给名字附带更多的信息

1、一个变量名就是一个小小的注释
反例:string id ; //example:"0x128a232b"
正例:string hex_id;
2、变量名带单位

带单位的值

3、附带额外信息
附带额外信息

1.1.5 决定名字的长度

名字隐含约束就是不能太长。

  • 1、在小的作用域可以使用短名字。
  • 2、输入长名字不再是问题。【内置补全功能】
  • 3、首字母缩写词和缩写
    经验原则:团队新成员可以理解这个名字含义。
  • 4、丢掉没用的词
    反例 :ConvertToString()
    正例: ToString()

1.1.6 利用名字的格式表达含义

利用下划线,大小写或者连字符可以装载更多含义。 在google的C++代码规范中:

  • kMaxOpenFiles表示常量,MAX_OPEN_FILES表示宏
  • state是局部变量,state_是成员变量

1.1.7 小结

    1. 使用专业的单词
    1. 避免空泛的名字
    1. 使用具体的名字描述细致的事物
    1. 给名字带上重要的细节
    1. 给作用域更大的名字采用更长的名字
    1. 有目的使用大小写和下划线

1.2 不起误解的名字

关键思想:要多问自己几遍,“这个名字会被别人误解成其他含义吗?“要仔细审视这个名字

反例: Filter("years <= 2010") 挑出还是减掉?
反例: Clip(text,length)是截断到,还是去掉?
正例:使用min和max表示极限
正例:使用first和last表示包含的范围
正例:使用begin和end表示包含/排除的范围

布尔型命名
正例:加上is,should,has,can,use变得含义更明确
正例:避免使用反义名词:bool disable_ssl=false;

1.3 审美

布局的三个原则:

  1. 使用一致的布局,让读者很快习惯这种风格。
  2. 让相似代码看上去相似。
  3. 相关的代码分组,形成代码块。
审美
  • 1、使用【从审美角度】让人愉悦的代码更容易
  • 2、安排换行是节奏保持一致和紧凑
  • 3、用方法规整不一致的东西
    反例

    正例
  • 4、在需要时,使用列对齐
    使用列对齐
  • 5、选择有意义的顺序,并保持一致
  • 6、把申明按照块组织起来
  • 7、把代码分成段落
  • 8、一致性比”正确“风格更重要

1.4 注释

关键思想:注释的目的就是尽量帮读者和作者了解一样多

注释

1、什么不需要注释

  • 不要为那些可以从代码快速推断的事实写注释
  • 不要为了注释而注释
  • 不要为不好的名字加注释,应该把名字改好

2、记录你的思想

  • 加入“导演评论”
  • 为代码的瑕疵做注释(//TODO:)


    流行的标注
  • 给常量加注释
    常量本身不需要解释,记录决定这个常量取值的想法,便于后续优化。
    3、站在读者的角度
  • 意料之中的提问
  • 公布可能的陷阱
  • 全局性的注释
    高级别的注释信息,包括文件,类,模块如何组织工作的。
  • 用注释来总结代码块,防止迷失细节

1.5 写出言简意骇的注释

言简意骇

关键思想:注释应该有很高的信息/空间率

  • 1、让注释保持紧凑
    反例

    正例
  • 2、避免使用不明确的代词(it,this)
  • 3、润色粗糙的句子
  • 4、精确描述函数的行为
    反例

    正例
  • 5、用输入/输出的例子来说明情况
  • 6、申明代码的意图
    【4,5,6用单元测试代替注释更妥】
  • 7、具名函数参数的注释
    使用嵌入式的注释,例如Function(/arg=/...)来解释函数的参数。
  • 8、采用信息量高的词,使得注释简洁

2 简化循环和逻辑

2.1 把控制流变得易懂

关键思想:把条件,循环以及其它对控制流的改变做的越“自然”越好。运用一种方式使得读者不用停下来重读你的代码

  • 1、条件语句中参数顺序
    if(length<=10) 还是 if(10>=length)?
    while(bytes_expected < bytes_recieved) 还是 while(bytes_expected > bytes_recieved) ?
    指导原则【和语言的语法一直】
比较的左侧 比较的右侧
被询问的表达式,它的值倾向于不断变化 用来作比较的表达式,它的值倾向于常量

if(object == null) 还是 if(null == object)?

  • 2、if/else语句块的顺序
    if条件选择标准:
    先处理正逻辑而不是负逻辑
    先处理简单的
    先处理有趣或者可疑的

  • 3、三目运算符
    关键思想:相对于追求代码最小行,一个更好的方式就是最小化人们理解他所需的时间
    建议:默认情况下都if/else, 三目表达式只在最简单的情况下使用。

  • 4、避免do/while循环
    使用while/for,而不是for/while, 把条件【危险】放到首先看到地方。

    提前告警

  • 5、从函数中提前返回
    使用卫语句,提前返回。【单出口】

  • 6、臭名昭著的goto

  • 7、最小化嵌套
    思维栈-可能导致理解困难。
    通过提前返回减少嵌套
    减少循环内的嵌套

2.2 拆分超长的表达式

1、解释变量
引入变量来解释子表达式。
2、最小化嵌套
用一个变量来代替一段代码。
3、使用德摩根定理

分别取反,转换与或

4、滥用短路原理
滥用短路

5、使用德摩根定理
6、复杂表达式,提取函数,提前返回

2.3 变量和可读性

1、减少变量
没有价值的变量
减少中间结果
减少控制变量

2、变小变量的作用域
让你的变量对尽量少的代码行可见
C++ if的作用域

差异?

3、只写一次的变量更好
操作一个变量的地方越多,越难确定他的值。

3 重新组织代码


3.1 抽取不相干的子问题

抽取不相干的子问题,建议:积极地发现并抽取不相干的子逻辑
我们指:

  • 看到某个函数或者代码块,问自己:这个代码的高层次目标是什么?
  • 对于每一行代码,问:他是直接为了目标而工作吗?这段代码高层次的目标是什么?
  • 如果足够的行数在解决不相干的子问题,抽取代码到独立的函数中。
  • 抽取纯工具代码
  • 其他多用途的代码
  • 创建大量通用代码
  • 项目专有代码
  • 简化已有接口
  • 按需重塑接口
  • 避免过犹不及
    小结:把一般代码和专有代码分离。

3.2 一次只做一件事

整理碎片
  • 1、任务可以很小
  • 2、从对象中抽取值

3.3 把想法变成代码

爱因斯坦:如果你不能把一件事情解释给你祖母听的话说明你还没有真正理解他

  • 1、像对着同事一样,用自然语言描述代码要做什么。
  • 2、注意描述中所用的关键词和短语。
  • 3、写出与描述匹配的代码

3.4 少写代码

关键思想:最好读的代码就是没有代码。

  • 1别费神不需要的功能【过度设计】
  • 2质疑和拆分需求 【故事拆分】
  • 3保持小代码库
    利用工具减少重复代码,并删除无用代码
代码库大小和维护难度
  • 4、熟悉你周边的库
    中肯建议:每隔一段时间,花15分钟来阅读标准库的所有函数/模块/类型的名字。

冒险、兴奋-绝地武士追求的并不是这些。--尤达大师

4 精选话题

4.1 测试与可读性

  • 1、使阅读易于阅读和理解
    测试应该具备可读性,以便其他程序员可以舒服的改变和增加用例。
    对使用者隐去不重要的细节,以便重要的细节更突出。
  • 2、创建最小的测试申明
    测试都可以提炼成:对于这样的输入/情形,期望这样的行为/输出.【BDD的描述更好】
  • 3、实现定制的“微语言”(DSL)
  • 4、让错误消息具备可读性
  • 5、 手工打造错误消息
  • 6、 测试函数命名
    规则:Test_<Function>_<Situation>
  • 7、TDD
    易测试产生更好的代码。
可测试性差的代码带来的设计问题

可测试性好的代码带来优秀设计
  • 8、走的太远
    主要有:
    为了可测试,牺牲可读性
    着迷100%可测试性
    测试成为开发的阻碍

4.2 设计并改进

通过一个例子来说明:演进式改进的过程。

小结

本书2018读的第一本书,大概花了10个多小时。本书在代码可读性的命名,布局,注释,循环控制,抽取函数,表达式,可测试性方面都有很不错的建议,值得内部分享和学习。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342