你真的思考过自己写的代码为啥这么垃圾吗?

共 1860字,需浏览 4分钟

 ·

2021-10-14 18:26

  点击上方“JavaEdge”,关注公众号

设为“星标”,好文章不错过!


大家所在项目组,一定遇到同类操作,但却有不同做法,尤其是祖传代码,一眼望去,可谓八仙过海各显神通。

大部分程序员也觉得团队开发应该保持编程习惯的一致性。但普遍理解的一致性都表现在较宏观层面,比如,数据库访问是叫DAO还是叫MapperRepository


团队虽然也有一些统一标准,但落地到编码,也没人一直给你 CR,所以要求就不是那么严格了。所以,我们才能欣赏到在代码写法百家争鸣。还是具体看几个案例来体会下吧~


千奇百怪的命名



这段代码可以了解到目前的分发渠道:

  • 网站

  • 只在Kindle

  • 全渠道

乍一看,你可能觉得没啥问题,可我就会好奇作者:

  • WEBSITEKINDLE_ONLY 分别表示什么?
    WEBSITE:作品只会在我们自己网站发布,KINDLE_ONLY:这部作品只会在 Kindle 的电子书商店里上架。

  • 二者是不是都表示只能在单独一个渠道发布?
    Yes

  • 既然含义类似,为何不都叫 XXX 或 XXX_ONLY?
    (⊙o⊙)…好像也是哦


所以,大家也看到了吧,类似含义的代码应该有一致的名称,就像很多团队都会把业务写到服务层,各种服务类类名也都是 XXXService

不一致的名字,一般都表示不同含义。比如,对那些非业务入口的业务组件,它们的名字就会不同,会更符合其具体业务行为,如BookSender:将作品发到翻译引擎。


我料想,这段代码作者给枚举值命名时,只分别考虑了应该叫啥名,却忽略了这个枚举值在整体中的地位。

至此,重构途径就很明白了:



方案不一致



现在某系统要向另外一个系统请求,需带一个时间戳,把这个时间戳按格式转成
String,主要做传输用,便于外部系统识别,也方便开发调试。

代码片段本身实现没问题,甚至还考虑到了 SimpleDateFormat 这个类非线程安全,所以,每次都创建一个新的 SimpleDateFormat 对象。

那我为什么还说它是有问题的呢?因为这种写法是 Java 8 之前的写法,而我们用的 Java 版本是 Java 8。


现在这是个Java8项目,完全可以使用 Java 8 的新日期时间API。所以项目也约定所有日期时间类型使用新API。


所以,这段代码本身实现没问题,但放在项目整体中,却没有和其它部分保持一致。

重构成使用新API即可:


一个项目应对同一个问题出现多个解决方案,没有统一约定,成员会根据自己的习惯随机选择方案,导致方案不一致。还比如判断字符串是否为空或空串,就有 Guava 和 Apache Commons Lang,都能做同样事情,所以,程序员也会根据自己熟悉程度选择其中之一来用,造成代码不一致。

这两个程序库是很多程序库的基础,经常因为引入了其它程序库,相应的依赖就出现在我们的代码中。所以,我们必须约定,哪种做法是我们在项目中的标准做法,以防出现各自为营。


代码中的不一致




在翻译引擎中创建作品的代码:

  • 首先,根据要处理的作品 ID,获取其中已审核通过的作品

  • 然后,发送一个 HTTP 请求在翻译引擎中创建出这个作品


看得出来什么问题吗?


这些代码不是一个层次的!
首先是获取审核通过的作品,是个业务动作,接下来的三行其实是在做一件事,也就是发送创建作品的请求,这三行代码:

  • 创建请求的参数

  • 根据参数创建请求

  • 最后把请求发送出去

三行代码合力完成发送创建作品的请求,而这件事整体才是个完整业务动作。

所以,这个函数有的是业务动作,有的是业务动作的细节。所以重构如下:


分清代码处于不同层次,基本功就是分离关注点一旦分解出不同关注点,还可进一步调整代码的结构。

像前面拆分出来的这个方法,我们已经知道它的作用是发出一个请求去创建作品,本质上并不属于这个业务类的一部分。
所以,还可通过引入一个新模型,将这个部分调整出去:


往期推荐


拥抱Kubernetes,再见了Spring Cloud

百度二面:一个线程OOM了,其它线程还能运行吗?

阿里四面:你知道Spring AOP创建Proxy的过程吗?

我是如何一步步让公司的MySQL支撑亿级流量的?


目前交流群已有 800+人,旨在促进技术交流,可关注公众号添加笔者微信邀请进群

喜欢文章,点个“在看、点赞、分享”素质三连支持一下~

浏览 38
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报