写点什么

Java 开发中常见的危险信号(中)

  • 2013-12-16
  • 本文字数:2217 字

    阅读完需:约 7 分钟

Dustin Marx 是一位专业软件开发者,从业已经有 17 年的时间,他拥有电子工程学士学位,还是一位 MBA。Dustin 维护着一个博客,专门介绍软件开发的各个主题。近日,他撰文谈到了Java 开发中常见的危险信号,提出了在日常的Java 开发中我们需要尽力避免的一些不正确的做法。感兴趣的读者可以参见本系列文章的第一部分

缺乏Javadoc 注释

我倾向于将所有的契约方法(特别是public 方法)都使用Javadoc 注释起来。此外,我还觉得对属性添加注释是必要的,注释要描述清楚属性存储的内容是什么。我听说有人拿代码是“自文档”的作为不写Javadoc 注释的借口,不过我对此却并不认同,我想对这些人说的是简单的Javadoc 注释可以表达出相同的信息,而阅读代码则需要花费更长的时间。虽然有些方法的名字会很长,但有时也无法准确地描述清楚期望的输入条件与输出结果。我认为很多Java 开发者(就像我一样)在使用JDK 时更喜欢阅读它的Javadoc 注释而不是JDK 源代码。既然如此,那我们自己编写的代码为何就要反其道而行之呢?我有时也会阅读源代码,这主要是因为注释不够充分,或是行为与描述的不一致,还有可能是我有理由相信注释过期了。

我还喜欢查看类属性的Javadoc 注释。有些人倾向于在public get/set 方法前加上属性描述信息,不过我不喜欢这种方式,因为这么做就是在假设属性总是有get/set 方法(我是不会做这种假设的)。

在方法的Javadoc 注释中描述实现细节

虽然我认为没有Javadoc 注释是个危险信号,不过错误地使用Javadoc 注释同样也是个危险信号。Javadoc 注释不应该说明实现细节,而应该关注于客户端对方法的期望(参数)与方法对客户端的期望(返回类型,还有可能是抛出异常等)。在真正的面向对象系统中,实现应该是可以在public 接口下进行修改的,因此将接口文档中的这些实现细节放到Javadoc 注释中是不恰当的做法。这是个“危险信号”,因为Javadoc 中存在的实现细节会让我怀疑注释的时效性。换句话说,这种注释经常会过期,随着代码的不断演化而出现错误。

源代码中的注释

虽然接口(通常是Javadoc)中缺乏注释是一种危险信号,不过方法体和其他源代码中的注释也可能是个危险信号,会导致潜在的问题。如果需要为代码添加注释以帮助人们理解代码的行为,那就很有可能是代码的复杂性过大(“注释是恶臭代码的芳香剂”,这句话有些滑稽,不过在一定程度上却真的如此)。就像文中提到的众多“危险信号”一样,有时我也认为源代码中的注释是有意义的,可以提供很多信息,这时就没有必要删除这些注释了。然而,我认为代码中的注释(不是接口描述的Javadoc 注释)应该尽量少一些,而且主要应该关注于“为什么”这么写而不是“如何做”。代码自身应该能够说明“如何”这一问题,不过很多时候是无法清楚地解释出“为什么”(由于客户/ 管理方向、设计决策、正式的接口需求、正式的算法需求等等)。

实现继承(extends)

我看到很多时候使用extends(实现继承)都很不错,也适合于相应的场景。但很多时候也存在使用不当的情况,实现继承会导致更多的麻烦。 Allen Holub 曾说到 extends 是邪恶的四人帮设计模式一书也用了很大的篇幅解释为何说组合要比实现继承更好。随着编写Java 代码时间的不断增长,更为重要的是随着我维护Java 代码时间的不断增长,我越来越觉得组合相对于实现继承的优势了。我确实看到了实现继承所带来的好处,不过更多的时候类是被“硬塞”到继承体系当中的,子类只不过是对 UnsupportedOperationExceptions 打洞或是“空实现”,因为他们所继承下来的方法并不适用于他们自己。加上 Effective Java 一书中所提及的继承问题(比如说具体类的 equals 与 hashCode 方法实现等),这真就成了一个大问题了。实现继承并不总是糟糕的,不过很多人经常没有正确地使用他们,因此我觉得这是个“危险信号”。

无作用的代码

程序中出现用不上的代码永远都不是一件好事。人们很快就会忘记它是怎么用的,为什么要这么用。不久之后,开发者就想知道这是不是出于某个原因被扔在那里的。无作用的代码不仅会无意义地增加代码长度,增加维护的复杂度,对于 IDE 来说,无作用的代码还有可能会被不小心调用,这种情况说明代码基出现了问题。

注释掉的代码

注释掉的代码可能不像可执行的、无意义的代码那么糟糕,因为至少它不会被不小心地调用,显然,这些代码是不会被用到的,不过这仍旧是个危险信号,因为它表明可能会出现潜在的代码基问题。就像无意义的可执行代码一样,注释掉的代码越多,人们就越难理解代码为何会出现在那里、为什么会被注释掉、不使用了为什么不将其删除掉。开发者不敢删除他们,因为留下来肯定是有原因的,只不过没人能够记起来原因是什么了。

To-Do 语句

现在越来越流行向代码添加“to-do”语句了,因为现代的 Java IDE 会为其提供特别的支持与特性。这些特性很有帮助,因为他们经常会将 todo 标记放在审查列表中,不过“to-do”注释依然是个危险信号,可能会带来与无意义的代码和注释掉的代码相同的问题。当然了,我也会使用“to-do”语句实现短期提醒,不过我觉得最好为其加上一个“过期日期”和联系信息,这样人们就可以清理他们了。加上过期日期与联系信息后,代码中的“to-do”注释就不会一直存在了,否则没有人会记得他们是干什么的,也没人敢删除他们,因为他们可能是在某个时间点被加进去的,很可能是经过某人的深思熟虑后才添加的。当我看到代码中的“to do”语句时,我真是没有任何的办法,只是想知道代码是不是缺少某些功能。

2013-12-16 10:223211
用户头像

发布了 88 篇内容, 共 273.9 次阅读, 收获喜欢 9 次。

关注

评论

发布
暂无评论
发现更多内容

1688商品列表数据接口(1688.item_search)丨1688API接口

tbapi

1688API接口 1688商品数据接口 1688商品列表数据接口 关键词搜索1688商品数据

英特尔的2023:以强大执行力推进产品、技术创新

E科讯

基于图神经网络的动态物化视图管理

KaiwuDB

KaiwuDB 物化视图管理

1688商品详情数据接口(1688.item_get)

tbapi

1688API接口 1688商品数据接口 1688商品详情数据接口 1688数据接口 1688商品详情API接口

传统架构VS云原生:如何更好的选择搭配

膨胀

#技术人的2023总结

一个 39.3T 的集群从TiDB v3.1.0迁移升级到 TiDB v7.1.2 的实践

TiDB 社区干货传送门

迁移 实践案例 版本升级 大数据场景实践 7.x 实践

TiDB是如何在国有大银行实现数据库业务“一换三”的

TiDB 社区干货传送门

7.x 实践

面试官:说一下MySQL主从复制的原理?

王磊

Java 面试

为什么美国服务器是业务国际化的首选?深入探讨其关键优势

一只扑棱蛾子

美国服务器

解析小红书笔记详情API的最佳实践与案例分享

技术冰糖葫芦

API

【火热报名中】TiDB 社区活动在北京:1月7日(周日)新年围炉茶会,来唠唠嗑,回顾过去一年,展望未来

TiDB 社区干货传送门

TiDB-Server 常用 API

TiDB 社区干货传送门

管理与运维

冲突管理最佳实践

俞凡

管理 最佳实践 沟通

【行云流水线】满足你对工作流编排的一切幻想~skr

京东科技开发者

赛迪顾问发布最新中国大数据市场报告,腾讯云稳居领导者行列

腾讯云大数据

大数据

喜讯!云起无垠获评ISC 2023数字安全创新能力百强双料大奖

云起无垠

一篇文章彻底搞懂TiDB集群各种容量计算方式

TiDB 社区干货传送门

监控 管理与运维 TiDB 源码解读 TiKV 源码解读

恭喜神州数码集团,荣获“TiDB 社区最佳贡献企业”

TiDB 社区干货传送门

什么是爬虫,为什么爬虫会导致服务器负载跑满

德迅云安全杨德俊

从0到1快速入门ETLCloud

谷云科技RestCloud

ETL 数据集成平台 数据集成工具

TiDB Placement Rule实战总结

TiDB 社区干货传送门

实践案例 6.x 实践 大数据场景实践 7.x 实践

Java开发中常见的危险信号(中)_Java_张龙_InfoQ精选文章