《代码之丑》——专栏笔记

2023-11-02

一、如何精确命名

错误1: 命名过于宽泛

命名过于宽泛,不能精准描述,这是很多代码在命名上存在的严重问题,也是代码难以理解的根源所在。

data、info、flag、process、handle、build、maintain、manage、modify

上面的词语是否经常出现在代码中?这都是一些十分宽泛的词语。首先,命名要能够描述出这段代码在做的事情。一个好的名字应该描述意图,而非细节。 说直白一些,就是我们的方法名应该和其内部逻辑强关联。

错误2: 用技术术语命名

我们当前有一个集合叫做bookList,这个名字看起来没什么,但它的名字和List类型“绑定”了,假如说这个集合是一个不可重复的集合,那就出现了这么一个现象,”一个名字是list的集合,它的类型却是set“。这样变很混乱。我们不如直接叫”books“,这就和”类型“不关联了。

总结

好的命名,是体现业务含义的命名。

二、乱用英文

一般来说,常见的命名规则是:

  • 类名是一个名词,表示一个对象。
  • 方法名则是一个动词,或者是动宾短语,表示一个动作。

案例1:一个函数名是 retranslation,其表达的意图是重新翻译,但作为函数名,它应该是一个动词,所以,正确的命名应该是 retranslate。

案例2:某个方法叫completedTranslate,它要做的是将一些章节的信息标记为“翻译完成”。它的问题在于completedTranslate并不是一个正常的英语函数名。从这个名字你能看出,作者想表达的是“完成翻译”,因为是已经翻译完了,所以他用了完成时的completed。但这个语法是错误的,若改成动宾结构,应是completeTranslation。

总结

编写符合英语语法规则的代码

三、重复代码

常见重复:

  • 复制粘贴的代码
  • 结构重复
  • if和else的两个代码块中的结构高度相似

if-else案例

if (user.isEditor()) { 
	service.editChapter(chapterId, title, content, true); 
} else { 
	service.editChapter(chapterId, title, content, false); 
}

上述代码,if代码块和else代码块的语句高度相似,唯一区别就是boolean类型的区别,这就是可以进行结构优化的地方,优化如下:

boolean approved = user.isEditor();
service.editChapter(chapterId, title, content, approved);

添加一个方法,用于获取boolean值,直接省去if-else语句了。

总结

千万不要复制粘贴,如果需要复制粘贴,首先应该做的是提取一个新的函数出来,把公共的部分统一处理。

四、长函数/长方法

多长的函数算长?这并没有一个确切的标准,不同的人、团队的标准都不一样。

在该专栏的作者看来,像 Python、Ruby 这样表达能力比较强的动态语言,大多数情况下,一行代码可以解决很多问题,所以,我对自己的要求大约是 5 行左右,并且能够用一行代码解决的问题,就尽量会用一行代码解决。对于Java 这样表达能力稍弱的静态类型语言,可以放宽10-20行。

长函数产生的原因:

  • 以性能为由,在早期,人们关注函数的调用会涉及“入栈出栈”,不如直接执行来得性能高。这种想法经过各种演变流传到今天。不过,这个观点在今天是站不住的。
  • 平铺直叙,说白了,就是像流水一样,把一整段逻辑都写在一个函数中,而不去进行函数/方法的封装。
  • 一次加一点,一开始代码不长,随着代码迭代慢慢变长。

五、大类

类之所以成为了大类,一种表现形式就是我们上节课讲到的长函数,一个类只要有几个长函数,那它就肯定是一眼望不到边了。大类还有一种表现形式,类里面有特别多的字段和函数,也许,每个函数都不大,但架不住数量众多。

产生原因:

  • 职责不单一
  • 字段未分组

六、长参数列表

每个程序员只要想到,一个函数拥有几十甚至上百个参数,内心就难以平静下来。函数的参数是为了传递、共享信息。

减少参数数量的方法:

  • 聚沙成塔:将参数列表封装成对象。
  • 动静分离:函数的参数有不同的变化频率,对于静态的,不常变化的参数可以不用传值,直接在方法内部赋值即可。
  • 告别标记:我们有时候会用“flag”,即一个boolean变量来作为参数,以告诉方法它想调用其中的哪个逻辑。这么做并不好,我们凭空造出了一个flag参数,多此一举。更有效的方法是直接将该方法的多个逻辑拆出来,封装成多个方法。

七、滥用控制语句

嵌套的代码也好,else 语句也罢,二者真正的问题在于,它们会使代码变得复杂,超出人
脑所能理解的范畴。我们可以通过提取单个元素操作,降低循环语句的复杂度,而用卫语
来简化条件表达式的编写,降低选择语句的复杂度。一个衡量代码复杂度的标准是圈复
杂度,我们可以通过工具检查一段代码的圈复杂度。

八、不一致问题

对于一个团队来说,一致是非常重要的,是降低集体认知成本的重要方式。常见的不一致问题如下:

  • 命名中的不一致:如枚举类中,各个常量的命名不统一。
  • 方案中的不一致:团队内的不同成员分别引入了不同的依赖(程序库),然后去使用其中的功能相同的方法。比如有的人引入了谷歌的Guava,有的人引入了Apache 的 Commons Lang,它们能做类似的事情,所以,程序员也会根据自己的熟悉程度选择其中之一来用,造成代码中出现不一致。
  • 代码中的不一致:体现在一个方法中的代码混乱,层次不统一。解决方案是将一个方法拆成多个方法,把业务代码和与业务关系不大的代码拆开。

九、落后代码风格

每一种有生命力的语言都会在自己的生命周期中不断地对语言本身进行改进,无论是引入新的语言特性,还是引入新的程序库,都会对代码的编写产生或多或少的影响。如Java8引入的Optional和Stream,通过Optional来避免空指针判断问题,通过Stream来代替循环。

总之,不断学习“新”的代码风格,不断改善自己的代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《代码之丑》——专栏笔记 的相关文章

随机推荐

  • web前端网页制作思路(只是思路)

    分享一下web前端网页制作的思路 首先 当你拿到一个项目关于网页设计的 比如类似于写一个类似于百度图片的搜索引擎 类似于这样 你会首先想到的是什么呢 先是这个背景呢 上面的文字呢还是说中间的文字 暂时我们只是讲一讲思路 谈一谈如何去做 好的
  • iOS编程基础-Swift(一)-Swift架构纵览

    Swift入门指南 iOS9 Programming Fundamentals With Swift 语言 第一章 从概念与实践上介绍Swift程序的结构 第二章 介绍Swift 函数 第三章 介绍Swift变量 第四章 介绍Swift对象
  • 计算机 国际顶尖级会议排名,计算机学科国际会议排名

    序号 会议名称 会议介绍 代表领域 1 ACM SIGCOMM ACM Conf on Communication Architectures Protocols Apps ACM的旗舰会议之一 也是网络领域顶级学术会议 内容侧重于有线网络
  • 电脑提示d3dcompiler_47.dll缺失怎么修复?

    我们再打开游戏或者软件的时候 电脑提示d3dcompiler 47 dll缺失无法打开运行需要怎么修复呢 d3dcompiler 47 dll是电脑系统非常重要的文件 是游戏跟软件运行必要的底层程序 小编今天就把修复教程分享给大家 修复教程
  • Seata 多路服务调用时事务不回滚解决办法

    最近使用了Seata作为分布式事务管理工具 在一般情况如 A服务调用B服务且A服务调用C服务 即A B A C这种服务调用链路 当其中任意一个服务报错 事务是可以回滚的 然而 稍微复杂一点的情况我发现seata事务居然不会回滚了 即A B
  • 关于知识图谱

    知识图谱 Knowledge Graph 什么是知识图谱 知识图谱这一概念最早由Google公司提出 其最初是为了提高搜索引擎的能力而设计的 知识图谱的定义有很多种 但是最为广泛接受的一种定义是 知识图谱是一种语义网络 什么是语义网络呢 网
  • Caesar密码的生成与破解

    背景 在密码学中 恺撒密码 英语 Caesarcipher 或称恺撒加密 恺撒变换 变换加密 是一种最简单且最广为人知的加密技术 它是一种替换加密的技术 明文中的所有字母都在字母表上向后 或向前 按照一个固定数目进行偏移后被替换成密文 例如
  • 和quicklook相似的软件_细数软件推荐爆文中出现比例较高的10款软件,看看谁出现最多...

    前言 软件推荐文一直是大妈爆文备选题材之一 作为一个比较喜欢用数据说话的鸽主 在电脑椅方面统计了不少数据 帮助不少人选择和使用电脑椅 所以这次也不例外 不过这回把手伸向了软件 软件推荐文中 很多人有长期使用的经验 所以对某些软件来说 就因为
  • 【C语言】输入一个十进制正整数,将它对应的二进制数的各位逆序,形成新的十进制数输出。题目分析及拓展应用。

    目录 一 题目及答案 二 对该题目的分析及详解 三 对该题的举一反三 1 将十进制数对应的n进制数各位逆序 形成新的十进制输出 2 将十进制数转换成相应的n进制数输出 一 题目及答案 如图 题目及答案如下 该程序完整代码如下 需要可自由复制
  • Eclipse使用入门

    工欲善其事 必先利其器 假若能熟练Eclipse 对于我们编写java程序会起到事半功倍的效果 大大提高我们工作效率 因此本篇博文 笔者只是针对刚刚入门java的新手 以便他们能尽快掌握Eclipse的使用 一 常用快捷键 这是使用工具的第
  • Quartus-II的安装教程

    Quartus II的安装教程 文章目录 Quartus II的安装教程 一 Quartus II的下载 二 Quartus II的安装 1 解压压缩包 2 进行安装 三 注册Quartus II 一 Quartus II的下载 百度网盘下
  • python pandas ExcelWriter FutureWarning: save is not part of the public API

    升级了Python 到3 10 然后pandas写的ExcelWriter也跟着升级了 以下是版本 pandas 1 5 0 xlwt 1 3 0 然后是执行原来的导数据到Excel的代码报错警告 FutureWarning save is
  • Mybatis的分页插件

    一 添加依赖
  • JAVA多线程与并发学习总结

    1 计算机系统 使用高速缓存来作为内存与处理器之间的缓冲 将运算需要用到的数据复制到缓存中 让计算能快速进行 当运算结束后再从缓存同步回内存之中 这样处理器就无需等待缓慢的内存读写了 缓存一致性 多处理器系统中 因为共享同一主内存 当多个处
  • MAC升级10.15不能使用[远程桌面连接]--解决方案

    MACBook升级10 15之后发现远程桌面无法打开 提示如下 各种找资料 主要是威锋网 均无法解决 只能换软件了 替代软件 Microsoft Remote Desktop 8 0 7版本 比较好用 软件下载地址 链接 https pan
  • java的各类型数据在内存中分配情况详解

    有这样一种说法 如今争锋于IT战场的两大势力 MS一族偏重于底层实现 Java一族偏重于系统架构 说法根据无从考证 但从两大势力各自的社区力量和图书市场已有佳作不难看出 此说法不虚 但掌握Java的底层实现对Java程序员来说是至关重要的
  • IC,ID卡二进制数据解析

    IC卡数据 一般10位 第一位 20 第四位 数据长度 第9位 校验位 最后一位03 如 20 00 00 04 03 CA C3 58 A9 03 ID卡 第一位02 第二位 数据长度 倒数第二位校验位 最后一位03 02 05 1D 0
  • Spyder设置代码自动补全

    1 spyder 代码自动补齐设置方式在tools gt preferences gt IPython console gt advanced Settings 下面 把User the greedy completer 勾选上 再把Aut
  • Linux笔记:增量备份程序rsync快速入门

    文章目录 目的 快速入门 常用选项 总结 目的 rsync是一款开源的文件增量备份程序 通常用于linux下文件的增量备份 这个程序可以将一个目录的文件备份到另一个目录中 并且在每次备份时还可以对文件进行比较 只复制更新有过改动的文件 rs
  • 《代码之丑》——专栏笔记

    一 如何精确命名 错误1 命名过于宽泛 命名过于宽泛 不能精准描述 这是很多代码在命名上存在的严重问题 也是代码难以理解的根源所在 data info flag process handle build maintain manage mo