吐槽篇 - 最近身边的代码真是有些无语...

最近,感觉身边见到的代码质量真是一言难尽。有些大厂回沈的同事啥的,但是代码写的我也是无语了,并且还不接受意见,感觉没法交流。列举下我最不能接受的几段代码,真实发生在身边的代码。

并不简单的格式问题

大厂同事提交的代码,就提交了一行@DataPermission这个注解:

@DataPermission(userAlias = "p", deptIdColumn = "create_dept",deptAlias = "p",userIdColumn = "create_user")
List<BizVo> findList(BizQueryDto queryDto);

是不影响功能,但是这个注解用的真是…

  • 属性后面的逗号没有统一的空格,并不要求非得有空格,但是自己的风格是不得一致啊,要不都不加,要不都加。
  • user相关的属性和dept相关的属性交替出现。是不是应该把user属性相关的放在一起,dept相关的属性放在一起才更易于理解和维护啊,非要拆开可以把alias放在一起,column相关放在一起啊,这个交替放是什么逻辑…

重点是这个注解的使用已经给出了如下的参考代码,但是大厂同事并没有理会示例代码的精髓:

@DataPermission(
	userAlias = "p", userIdColumn = "create_user",
	deptAlias = "p", deptIdColumn = "create_dept"
)
List<BizVo> findList(BizQueryDto queryDto);

但是大厂同事强调这个无所谓,并且他们之前都是借助格式化工具来自动完成代码格式化的。
自动化没有问题,但是是不应该保证提交到代码仓库上的代码已经格式化过啊,但是代码库上的代码就是我最上面列出的那样。

我的观点是,合格的程序员应该保证自己代码风格、格式的一致性,说简单了就手里的活干的立正些。格式并不仅仅只是简单的问题,是能侧面反应出一个程序员思维的严谨性、责任心的,并且对后续的维护也是有帮助的。

if和Optional的嵌套使用

大厂同事提交的代码,ifOptional嵌套在一起:

if (StringUtils.isNotBlank(eventType)) {
    setEventType(Optional.ofNullable(AuditEventTypeEnum.codeOf(eventType))
            .map(AuditEventTypeEnum::getMessage)
            .orElse(eventType));
}

如上代码既有if又有Optional,但其实Optional就是做if null判断的,并且嵌套在一起真的有些层级过多(臃肿)、可读性差。
我给出了如下的改进建议,仅使用Optional便可替换掉原来的if

Optional.ofNullable(eventType)
   .map(AuditEventTypeEnum::codeOf)
   .map(AuditEventTypeEnum::getMessage)
   .ifPresent(this::setEventType);

大厂同事看了一眼就又是一顿掰扯,然后说我给的代码之后是不还得再调用一次setEventType这个方法,我都无语了,压根就没看懂就跟我一顿掰扯。然后看懂代码了,又说AI说Optional可读性没有if好,我就又无语了,原来的代码是ifOptional都用了,并且嵌套在一起用了,都把Optional用成这样了,还跟我说Optional可读性不好,他要是不用Optional只用if,我都不会给他提这个优化建议了,既然都用了Optional了,是不就该把它用明白了,别半吊子啊…接不接收的无所谓,但是别人给提的建议是不需要好好理解一下啊。

魔法变量

继续,大厂同事的新代码:

if (StringUtils.isNotBlank(eventSuccess)) {
    setEventSuccess(AUDIT_EVENT_SUCCESS.equals(eventSuccess) ? "成功" : "失败");
}

这个"成功""失败"是什么鬼,就不能定义个枚举、常量啥的的吗。
并且,工程里是有相关的常量定义的,就不能找一下吗…

代码变量名和数据库列名非得不一致

比如数据库里按照parentCode查询,代码里的参数名就叫parentId,
数据库里照层级level查询,代码里的参数名就叫deep,
这个是要故意给后续的维护人员增加理解上的的困难吗。
然后大厂同事跟我掰扯DDD中的统一语言,代码可以和数据库中的列名不一致,但是也不用这么刻意地不一致吧…

接口参数的隐藏规则

大厂同事给出的REST接口定义如下:

GET /tree?parentId=111

正常人应该都会理解为查询parentId下的子节点。
但是还有隐藏规则,参数parentId的值为0时会查询前N层的节点。
这是给维护人员挖坑吗,这种隐藏的规则鬼知道啊,时间长了谁会记得啊。
我给的建议是拆分成2个参数:level, parentId,即按层查询传输level参数,查询子节点则传输parentId参数。

SVG的字体的掩耳盗铃

大厂同事实现了后端生成文本SVG的功能,即生成SVG格式(XML格式)的图片,图片的内容是一段文字。
大厂同事集成了一堆组件,一顿生成SVG图片,并集成了自定义的字体来计算文字的宽度及SVG图片的宽度。

但是我实际测试SVG图片的宽度不对,文字显示不全。我提出了这个问题,大厂同事又是一顿掰扯,说我没更新代码、他自己测试是好用的…

SVG本质上就是一段XML定义,大多数前端开发者应该都能手写下面这段代码:

<svg xmlns='http://www.w3.org/2000/svg' width='400' height='80'>
	<text x='0' y='60' font-size='25' fill='rgba(200,200,200,0.25)'>QuickStart自定义登录页面</text>
</svg>

我的大厂同事为了计算SVG的宽度,硬给text塞了一个font-family属性,属性值是后端引入的一个字体:

<svg xmlns='http://www.w3.org/2000/svg' width='400' height='80'>
	<text x='0' y='60' font-size='25' font-family="我是你不认识的字体" fill='rgba(200,200,200,0.25)'>QuickStart自定义登录页面</text>
</svg>

关键这个字体只有后端服务认识,真正集成到用户的浏览器中,用户的浏览器环境根本不认识这个字体,根据这个字体计算的宽度对真实的用户并不起作用啊,掩耳盗铃吗…

我给的建议:

  • 移除多余的组件,手写SVG XML为一个配置属性,仅是替换SVG XML中的文本和宽度值。没必要引入多余的依赖。
  • 移除字体,根据font-size计算宽度值(并未实测,理论上font-size可以计算多文字的叠加宽度,哪怕加些buffer值)。

最终,移除了后端生成SVG这个功能,由前端根据文字生成SVG…

但是,后端有问题的SVG生成代码还依旧保留在代码库中,使用者可以看到并使用相应的接口。这个是我最不推荐的,没用的代码就该被删除,不要保留在代码库中,想要找回代码可通过git提交记录找回。废弃的代码、有问题的代码还保留在代码库中,会给后续的维护带来负担、引入不必要的麻烦,况且有问题的代码还要给用户使用吗,给用户挖坑吗?
但现实是,它就这么一直在代码库中…

结论

还有好多例子,下次有机会再分享吧。
不爱掰扯了,改不改无所谓了,爱咋写咋写吧…
准备下班了,别耽误我回家带娃了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗小爬EX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值