一、13类典型坏味道

01 | 缺乏业务含义的命名:如何精准命名?

  • 不精准的命名:主要体现在命名过于宽泛,不能精准描述,这是很多代码在命名上存在的严重问题,也是代码难以理解的根源所在,所以命名要能够准确的描述出这段代码在做的事情
  • 技术术语命名:在实际的代码中,技术名词的出现,往往就代表着它缺少了一个应有的模型。在一个技术类的项目中,这些技术术语其实就是它的业务语言。但对于业务项目,这个说法就必须重新审视了。

总结:好的命名,是体现业务含义的命名。在我看来命名做到不言自喻就可,让后来者看到你的命名就大致知道这段代码的大致详情即可。

02 | 乱用英语:站在中国人的视角来看英文命名

  • 违反语法规则的命名:常见的命名规则是:类名是一个名词,表示一个对象,而方法名则是一个动词,或者是动宾短语,表示一个动作。
  • 不准确的英语词汇:最好的解决方案还是建立起一个业务词汇表,千万不要臆想(可以在开发前,专门开会制定业务词汇表,这样大家均用同一套词汇,更利于开发。用集体智慧,而非个体智慧。)
  • 英语单词的拼写错误:常见问题,可能是粗心大意,一般开发工具会提示,但是还是会出现。

总结:编写符合英语语法规则的代码。在我看来该坏味道其实就是自身细心程度和团队开发的整体性问题,集大家之想,必将降低问题的出现

03 | 重复代码:简单需求到处修改,怎么办?

  • 复制粘贴的代码:不要使用复制粘贴。真正应该做的是,先提取出函数,然后,在需要的地方调用这个函数。复制粘贴的代码是一颗随时可能爆炸的炸弹。
  • 结构重复的代码:一旦出现重复的结构,就提取公共方法,避免代码的冗余。
  • if 和 else 代码块中的语句高度类似:只要你看到 if 语句出现,而且 if 和 else 的代码块长得又比较像,多半就是出现了这个坏味道

总结:不要重复自己,不要复制粘贴。

04 | 长函数:为什么你总是不可避免地写出长函数?

  • 以性能为借口:性能优化不应该是写代码的第一考量。
  • 把代码平铺直叙地摊在那里:关注点越多越好,粒度越小越好。
    • 把多个业务处理流程放在一个函数里实现;
    • 把不同层面的细节放到一个函数里实现。
  • 只是每次增加了一点点:任何代码都经不起这种无意识的累积,每个人都没做错,但最终的结果很糟糕。

总结:把函数写短,越短越好。

05 | 大类:如何避免写出难以理解的大类?

如果一个类里面的内容太多,它就会超过一个人的理解范畴,顾此失彼就在所难免了。、

主要是将大类拆分成小类。我们需要认识到,模块拆分,本质上是帮助人们降低理解成本的一种方式。

  • 职责不单一:把不同的职责拆分开来,我们需要对不同内容的变动原因进行分析,而支撑我们来做这种分析的就是单一职责原则。
  • 字段未分组

总结:把类写小,越小越好

06 | 长参数列表:如何处理不同类型的长参数?

  • 变化频率相同:则封装成一个类。
  • 变化频率不同的话
    • 静态不变的,可以成为软件结构的一部分;
    • 多个变化频率的,可以封装成几个类。

参数列表中经常会出现标记参数,这是参数列表变长的另一个重要原因。对于这种标记参数,一种解决方案就是根据这些标记参数,将函数拆分成多个函数。

总结:减小参数列表,越小越好

07 | 滥用控制语句:出现控制结构,多半是错误的提示

  • 嵌套的代码
  • else 语句:一种典型的重构手法:以卫语句取代嵌套的条件表达式,不要使用 else 关键字
  • 重复的 switch:以多态取代条件表达式
  • 循环语句

总结:循环和选择语句,可能都是坏味道

08 | 缺乏封装:如何应对火车代码和基本类型偏执问题?

  • 过长的消息链,或者叫火车残骸

例如:

String name = book.getAuthor().getName();

解决这种代码的重构手法叫隐藏委托关系(Hide Delegate),说得更直白一些就是,把这种调用封装起来(要想摆脱初级程序员的水平,就要先从少暴露细节开始)

  • 基本类型偏执:这种引入一个模型封装基本类型的重构手法,叫做以对象取代基本类型(Replace Primitive with Object)。

总结:构建模型,封装散落的代码。

09 | 可变的数据:不要让你的代码“失控”

  • 满天飞的 Setter:相比于读数据,修改是一个更危险的操作。缺乏封装再加上不可控的变化,在我个人心目中,setter 几乎是排名第一的坏味道

    • 消除 setter ,有一种专门的重构手法,叫做移除设值函数(Remove Setting Method)。总而言之,setter 是完全没有必要存在的。
  • 可变的数据

    • 所有的字段只在构造函数中初始化;
    • 所有的方法都是纯函数;
    • 如果需要有改变,返回一个新的对象,而不是修改已有字段。
      总结:可变数据最直白的体现就是各种 setter。setter 一方面破坏了封装,另一方面它会带来不可控的修改,给代码增添许多问题。解决它的一种方式就是移除设值函数(Remove Setting Method),将变化限制在一定的范围之内。限制可变的数据。

10 | 变量声明与赋值分离:普通的变量声明,怎么也有坏味道?

  • 变量的初始化:一个变量的初始化是分成了声明和赋值两个部分,而我这里要说的就是,变量初始化最好一次性完成。尽可能使用不变的量,在能够使用 final 的地方尽量使用 final,限制变量的赋值
  • 集合初始化:传统的集合初始化方式是命令式的,而今天我们完全可以用声明式的方式进行集合的初始化,让初始化的过程一次性完成。使用java9的集合新特性

11 | 依赖混乱:你可能还没发现问题,代码就已经无法挽救了

  • 缺少防腐层:会让请求对象传导到业务代码中,造成了业务与外部接口的耦合,也就是业务依赖了一个外部通信协议。一般来说,业务的稳定性要比外部接口高,这种反向的依赖就会让业务一直无法稳定下来,继而在日后带来更多的问题。解决方案自然就是引入一个防腐层,将业务和接口隔离开来。
  • 业务代码中出现具体的实现类:实际上是违反了依赖倒置原则。因为违反了依赖倒置原则,业务代码也就不可避免地受到具体实现的影响,也就造成了业务代码的不稳定。识别一段代码是否属于业务,我们不妨问一下,看把它换成其它的东西,是否影响业务。解决这种坏味道就是引入一个模型,将业务与具体的实现隔离开来。
    总结:代码应该向着稳定的方向依赖。

12 | 不一致的代码:为什么你的代码总被吐槽难懂?

  • 命名中的不一致:表示类似含义的代码应该有一致的名字
  • 方案中的不一致
  • 代码中的不一致

13 | 落后的代码风格:使用“新”的语言特性和程序库升级你的代码

  • Optional的使用:Optional 的引入可以减少由于程序员的忽略而引发对空对象的问题。团队内部可以约定,所有可能返回空对象的地方,都要返回 Optional,以此降低犯错的几率。
    参考:https://blog.csdn.net/qq_46728644/article/details/125486253
  • 函数式编程:是一个影响代码整体风格的重要编程范式

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

学习自:https://time.geekbang.org/column/intro/100068401 如有侵权请及时联系

《代码之丑》学习总结相关推荐

  1. 《HBase权威指南》一导读

    前 言 HBase权威指南 你阅读本书的理由可能有很多.可能是因为听说了Hadoop,并了解到它能够在合理的时间范围内处理PB级的数据,在研读Hadoop的过程中发现了一个处理随机读写的系统,它叫做H ...

  2. 《JS权威指南学习总结--开始简介》

    本书共分成了四大部分: 1.JS语言核心 2.客户端JS 3.JS核心参考 4.客户端JS核心参考 其中 <JS权威指南学习总结--1.1语法核心> 是:第一部分JS语言核心 各章节重点 ...

  3. JavaScript 权威指南-学习笔记(一)

    本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! JavaScript 权威指南-学习笔记 ...

  4. Hadoop权威指南学习笔记三

    HDFS简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考.有什么不到之处还望指出,一起学习一起进步. 转载请注明:http://blog.csdn.net/my ...

  5. HBase权威指南 高清中文版 PDF(来自linuxidc)

    内容提要 <HBase权威指南>由乔治(Lars George)著,探讨了 如何通过使用与HBase高度集成的Hadoop将 HBase的可 伸缩性变得简单:把大型数据集分布到相对廉价的商 ...

  6. Hadoop权威指南学习笔记一

    Hadoop简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考,有什么不到之处还望指出.一起学习一起进步. 转载请注明:http://blog.csdn.net/ ...

  7. 802.11基本概念介绍【802.11 无线网络权威指南学习总结1】

    802.11基本概念介绍[802.11 无线网络权威指南学习总结1] 1.802.11网络技术介绍 IEEE 802 规格的重心放在 OSI 模型最底下的两层,因为它们同时涵盖了实体(physical ...

  8. mysql权威指南 代码_mysql权威指南学习札记

    mysql权威指南学习笔记 1,mysql的标示符最多就64个字符 2,drop table table1,table2,table3;删除多个table的时候用,号分隔开,为了避免不必要的错误,我们 ...

  9. symfony权威指南学习之一:symfony 介绍

    symfony权威指南学习之一:symfony 介绍 一.symfony 简介        symfony 是一个完整的 web 应用开发框架,它为加速开发提供了几个关键功能. 首先,它把 web ...

  10. Http权威指南学习研究

    学习时间:                                   该学习:第六章  6.6小节   加油   185页 2017年5月15日15:13:00 今天任务: 看完前两章节: ...

最新文章

  1. 【 FPGA 】UltraFast设计方法学:时序约束
  2. Spring原理简述
  3. python打包安卓的方法_30个你想打包带走的Python技巧(下)
  4. 你不知道的 字符集和编码(编码字符集与字符集编码)
  5. linux写入系统状态到文件夹,实验二 Linux系统简单文件操作命令
  6. isnull pivot server sql_使用SQL Server中的“Pivot”将行转换为列
  7. Linux设备驱动——PCI总线的初始化
  8. 安卓简单实现百度地图
  9. python实现通讯录代码
  10. android一键改机之真改机build.prop
  11. C语言求13位条形码的验证码,c语言问题 条形码输入
  12. 联想android怎么解密,联想G886手机如何解密
  13. JAVA多态的理解及应用
  14. 【京东电商网站主界面仿写——CSS第一部分】
  15. python+excel接口自动化测试(实现 数据分离,token获取,数据依赖,发送邮件)
  16. #mkdir无法创建目录权限不够*
  17. 洛谷10月月赛II题解
  18. 2015百度之星资格赛1002
  19. linux脚本加密 upx,#加解密#LinuxShell加密解密方法(shc/gzexe/UPX)
  20. Matlab运用kron()函数计算Kronecker乘法

热门文章

  1. java spider爬虫_一个简单的java网络爬虫(spider)
  2. MTK6762 Helio P22 安卓核心板模块应用
  3. 朱义晨作业 17037099
  4. FZU 2213 Common Tangents(公切线)
  5. 【揭秘】CSDN博客上,超过百万访问量的Android牛人都是谁?
  6. java 订单模块实现
  7. KW代码检查规则-RLK.JNDI
  8. ES集群状态一直yellow状态引发的思考
  9. 《我与长安城的朝花夕拾》
  10. solr和elasticsearch