前段时间在看《架构整洁之道》,里面提到了:构建一个好的软件系统,应该从写整洁代码做起。毕竟,如果建筑使用的砖头质量不佳,再好的架构也无法造就高质量的建筑。趁热打铁,翻出《代码整洁之道》再刷一遍。

《代码整洁之道 Clean Code》学习笔记 Part 1

衡量代码质量的唯一标准:WTF/min

第一章 整洁代码

糟糕代码的代价

  • 理解、维护成本高。每次修改影响到好几处代码

  • 每次修改都会产生意想不到的问题,导致惧怕、抵触改动

  • 初期进展“迅速”,后续生产力持续下降,趋向于零

  • 破窗理论:如果对糟糕的代码放任不管,就会使人们争相效仿,甚至变本加厉

  • 不要想着先写出糟糕的代码,然后改进。勒布朗法则:Later equals never

  • Dealine 不是写出糟糕代码的借口,赶上 dealine 的唯一方法是写出 Clean Code

什么是 Clean Code

  • 消除重复
  • 只做一件事
  • 提高表达力:代码本身能够清晰地表达意图,不需要注释。良好的命名是提高表达力的重要手段
  • 提早构建简单抽象(小规模抽象)
  • 代码意图直截了当,不隐藏设计意图,叫 bug 难以隐藏
  • 减少依赖关系,使之便于维护
  • 性能调至最优,避免诱导他人来乱优化
  • 几乎没有改进的余地。如果你企图改进他,总会回到原点

童子军军规

Make the camp cleaner than when you arrived.

每次提交代码时,代码都比 checkout 时更干净,那么代码就不会变坏:

  • 改好一个变量名
  • 拆分一个过长的函数
  • 消除一点点重复代码
  • 清理一个嵌套 if

总结

“消除重复,只做一件事,提高表达力,小规模抽象”概括了本书的全部内容。

第二章 命名

为什么需要好的命名

读代码和写代码的时间大于 10:1,好的名字让人更容易理解和修改代码,节省下来的时间远远大于起名字所花的时间。

  • 命名是一件很严肃的事情,是一个程序员的基本功
  • 如果发现给函数或者类起一个合适的名字很困难,要反思函数和类的设计是否合理、是否过于复杂,违反了单一职责原则

名副其实

  • 变量、函数或者类的名字应该可以回答:它为什么存在,做什么事,该怎么用。如果还需要注释来补充,就不算名副其实
  • 一个好的函数名只要看名字就知道干了什么事,而不需要跳转进去看实现,有助于保持在一个较高的抽象层级上快速理解代码

一些命名建议

  • 类名和对象名应该是名词或名词短语
  • 函数或方法名应该是动词或动词短语
  • 不要自己发明一些奇奇怪怪的缩写
  • 使用可搜索名称,变量名的长短应和作用域大小相对应
  • 通常单字母变量名不是好的选择,除非用作循环控制变量的 i、j、k(较小的作用域)
  • 统一术语:不要混用 start/begin,get/fetch/retrieve、controller/manager/mgr... 混用多种术语让人困惑,增加记忆负担
  • 避免歧义:如集合有一个 add 方法,可能是对两个集合进行求和,如果想向集合插入数据,再用 add 命名就不合适,应该用 insert 或 append
  • 避免误导:避免名字中的 l10O
  • 避免很长的名字中藏着细微的差别:XYZControllerForEfficientHandlingsOfStrings 和 XYZControllerForEfficientStorageOfStrings
  • 使用编程相关术语,如设计模式 Singleton、Facade、Visitor...
  • 使用特定领域/行业的术语
  • 添加有意义的语境:命名空间、类、函数都可以提供语境。如果没有这么做,可以添加前缀
  • 避免无意义的语境:例如开发一个名为 GasStationDeluxe 的应用,给其中每一个类都加上 GSD 前缀就是没有意义的

避免无意义的区分

  • 如果有三个类:Product、ProductInfo、ProductData,人们无法从名字中判断这三个类有什么区别,到底该用哪一个类。其中 Info、Data 就是毫无意义的区分

  • customer 和 customerInfo、account 和 accountData、message 和 theMessage,这些都是无意义的区分,即无法通过名字区分这两个变量有什么区别

例子

copyChars(char* a1, char* a2) copyChars(char* dst, char* src)
thread t1;
thread t2;
thread mainThread;
thread signalHandlingThread;

避免使用编码

  • 避免匈牙利命名法,历史产物,现在编译器可以进行类型检查
  • 避免成员变量的 m_ 前缀,当类足够小的时候,就不需要成员前缀*
  • 不要给接口类名加 I 前缀

注1:关于这一点,应该遵循特定项目/组织的规定,比如 Google 的 C++ 编码规范要求成员变量使用 _ 后缀,常量使用 k 前缀...

注2:命名规范也可也通过工具进行自动检查,如 clang-tidy

第三章 函数

这章后面单独说

第四章 注释

  • “别给糟糕的代码加注释——重新写吧”
  • 好的代码有表达力(Self-documenting),不需要注释
  • 注释总是一种失败:注释可能说谎,修改代码有时会忘记修改注释,只有代码才能忠实的告诉你它做的事
  • 短小的函数、良好的命名表达力不差于注释
  • 注释不是越多越好,废话注释反而会干扰正常的代码阅读:本来结构紧凑的代码可以一览无遗,但是如果混入了大量的废话注释,就可能需要来回滚动屏幕才能看到全览

可以出现的注释

  • 版权声明
  • Public API 的说明(如 doxygen 格式的接口说明)
  • TODO 注释
  • 对意图的解释、阐述(强调 WHY,而不是 HOW)
  • 警示、强调

要避免的注释

  • 日志式注释:作者、变更记录等等 --> git 才是这些信息的归宿
  • 位置标记、分割,如 ///////////// INCLUDE ////////////////////
  • 注掉的的代码应该删掉,真的需要也可以从 git 历史中找到
  • 废话注释、循规蹈矩的注释:The constructor, Destructor, the name, the version...
  • 如果发现写注释的时候,只是机械的体力劳动,甚至只是复制粘贴, 那么这种注释多半没什么用,写了也未必有人看

第五章 格式

格式化工具

我几乎没有操心过格式问题:缩进几个空格、在什么位置放括号、等号两边是否有空格、每行最多多少字符……所有这些问题都不应该花费任何精力。只要配置好了格式规则,有很多工具(如 clang-format)可以帮我们自动格式化代码,甚至可以配置为在保存文件或者 git commit 时,自动调用格式化工具格式化代码。

垂直格式

在本章中,有一点 clang-format 这样的工具可能还做不到,那就是垂直格式

  • 以适当空行分割
  • 相关函数、概念相关的代码应该放在一起
  • 避免废话注释把关联紧密的代码分开
  • 自顶向下:被调函数应该放在执行调用函数的下面。建立一种自顶向下贯穿代码的信息流:重要的高层抽象逻辑放在源文件的开头,越接近底层的实现细节越靠近文件的底部。这样只要阅读源码文件的上面几个函数就能大致了解整个文件的作用,无需了解低层实现细节

Team Rules

成熟的程序员不该纠结格式规则。每个程序员都有自己喜欢的规则,但只要在一个团队项目中,那么团队规则说得算。

说到这里,我想起了一个真实的小故事:博世的汽车多媒体部门,很多软件模块的代码缩进是 3 个空格。我一直好奇这奇葩的规则是怎么来的,直到某次例会,组里某个在博世工作了十几年的资深大佬讲出了背后的故事:制定编码规范的时候一部分程序员坚持用 2 个空格,而另外一部分坚持 4 个空格,谁也无法说服对方,最终各让一步,决定使用 3 个空格缩进。

《代码整洁之道 Clean Code》学习笔记 Part 1的更多相关文章

  1. 2015年第11本:代码整洁之道Clean Code

    前一段时间一直在看英文小说,在读到<Before I fall>这本书时,读了40%多实在看不下去了,受不了美国人啰啰嗦嗦的写作风格,还是读IT专业书吧. 从5月9日开始看<代码整洁 ...

  2. 代码整洁之道Clean Code笔记

    @ 目录 第 1 章 Clean Code 整洁代码(3星) ?为什么要整洁的代码 ?什么叫做整洁代码 第 2 章 Meaningful Names 有意义的命名(3星) 第 3 章 Function ...

  3. 代码整洁之道Clean Code 读后感After Reading

    1.有意义的命名 名副其实,避免误导 做有意义的区分,简单明了2.函数 短小,职责单一 别重复自己3.注释 用代码来阐述 可怕的废话4.格式 垂直格式,垂直距离,空范围 横向格式,水平对齐,缩进5.错 ...

  4. 《代码整洁之道》(Clean Code)- 读书笔记

    一.关于Bob大叔的Clean Code <代码整洁之道>主要讲述了一系列行之有效的整洁代码操作实践.软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关.这一点,无论是敏捷开发流派 ...

  5. 读《Clean Code 代码整洁之道》之感悟

    盲目自信,自认为已经敲了几年代码,还看什么整洁之道啊.我那可爱的书架读懂了我的心思,很明事理的保护起来这本小可爱,未曾让它与我牵手 最近项目中的 bug 有点多,改动代码十分吃力,每看一行代码都带一句 ...

  6. 《代码整洁之道》ch1~ch4读书笔记 PB16110698 (~3.8 第一周)

    <代码整洁之道>ch1~ch4读书笔记  <clean code>正如其书名所言,是一本关于整洁代码规范的“教科书”.作者在书中通过实例阐述了整洁代码带来的种种利处以及混乱代码 ...

  7. <读书笔记> 代码整洁之道

    概述      1.本文档的内容主要来源于书籍<代码整洁之道>作者Robert C.Martin,属于读书笔记. 2.软件质量,不仅依赖于架构和项目管理,而且与代码质量紧密相关,本书提出一 ...

  8. 《代码整洁之道》ch5~ch9读书笔记 PB16110698(~3.15) 第二周

    <代码整洁之道>ch5~ch9读书笔记 本周我阅读了本书的第5~9章节,进一步了解整洁代码需要注意的几个方面:格式.对象与数据结构.错误处理.边界测试.单元测试和类的规范.以下我将分别记录 ...

  9. <代码整洁之道>、<java与模式>、<head first设计模式>读书笔记集合

    一.前言                                                                                       几个月前的看书笔记 ...

  10. 如何写出如散文般的代码――《代码整洁之道》读书笔记(Ch1-Ch3)

    不知道有多少人像我一样,程序出现问题时添加函数添加变量解决,变量名用a,b,c等"简单"的字母来表示.不知道有多少人像我一样,看完自己的代码,心里暗骂"什么玩意儿!&qu ...

随机推荐

  1. 2021-10-26:给定一个数组arr,arr[i] = j,表示第i号试题的难度为j。给定一个非负数M。想出一张卷子,对于任何相邻的两道题目,前一题的难度不能超过后一题的难度+M。返回所有可能的卷

    2021-10-26:给定一个数组arr,arr[i] = j,表示第i号试题的难度为j.给定一个非负数M.想出一张卷子,对于任何相邻的两道题目,前一题的难度不能超过后一题的难度+M.返回所有可能的卷 ...

  2. SQL Server临时表删除

    SQL Server临时表删除 IF (SELECT object_id('tempdb..#tmpacqichu')) is not null DROP TABLE #tmpacqichu

  3. 沁恒 CH32V208(五): CH32V208 运行FreeRTOS示例的说明

    目录 沁恒 CH32V208(一): CH32V208WBU6 评估板上手报告和Win10环境配置 沁恒 CH32V208(二): CH32V208的储存结构, 启动模式和时钟 沁恒 CH32V208 ...

  4. 【爬虫+数据清洗+可视化】用Python分析“淄博烧烤“的评论数据

    目录 一.背景介绍 二.爬虫代码 2.1 展示爬取结果 2.2 爬虫代码讲解 三.可视化代码 3.1 读取数据 3.2 数据清洗 3.3 可视化 3.3.1 IP属地分析-柱形图 3.3.2 评论时间 ...

  5. R 包 pathview 代谢通路可视化

    pathview R 包是一个集成 pathway 通路数据与可视化的工具集.它用于把用户的数据映射并渲染到相关的 pathway 通路图上,用户只需要提供基因或者化合物数据(gene or comp ...

  6. 2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索。 在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度) 然后输出该节点的值。(如果节点的深度为 D,则其

    2023-06-14:我们从二叉树的根节点 root 开始进行深度优先搜索. 在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度) 然后输出该节点的值.(如果节点的深度为 D,则其 ...

  7. dpkg 安装mysql

    名称 版本 系统 Ubuntu 16.04 MySQL 5.7.26 下载安装包 wget https://dev.mysql.com/get/Downloads/MySQL-8.mysql-serv ...

  8. TVM Deploy Runtime[施工中]

    本文地址:https://www.cnblogs.com/wanger-sjtu/p/17291070.html tvm 中在部署时有多个选择,最开始的graph exectuor runtime . ...

  9. C++'s most vexing parse

    本文地址 https://www.cnblogs.com/wanger-sjtu/p/16876846.html C++'s most vexing parse 是 Scott Meyers 在其名著 ...

  10. WPF 项目使用 Grpc.Tools

    1 WPF 项目使用 Grpc.Tools 1.1 方法一 把 proto 文件和 Grpc.Tools 单独建一个类库项目,WPF 项目引用这个类库项目. 解决 Grpc.Tools 自动生成的 C ...