当前位置: 首页 > 科技观察

拯救Java代码风格强迫症

时间:2023-03-17 10:00:19 科技观察

本文源于上一个持续交付咨询项目。当时我在指导客户团队的Java工程师做CodeReview,发现一个很有意思的现象:有一个工程师特别关注CodeStyle。所以在CodeReview的时候,大部分时间都是工程师指出格式不对的地方,团队却没有找到改进的方法,每次的结论都是“我下次会多注意”。CodeStyle认真的态度,于是萌生了“如何拯救CodeStyle强迫症”的想法。KeypointsCodeStyle不是个人喜好问题,会影响工作效率,团队应该作为工程实践来关注。CodeStyle需要端到端的工具支持,以尽早解决问题并避免技术债务。以Checkstyle为核心工具支持Java项目的CodeStyle实现。1.代码风格是一种工程实践。我是右边风格的忠实粉丝。如果你让我在我正在做的项目中看到左边样式的代码,你猜我会是什么反应。好吧,也许我确实对代码风格有一些强迫症,但其实CodeStyle不仅仅是代码好看不好看那么简单。如果不按照惯例写代码,甚至会让读者看不懂。privateListenerlistener=newListener()//SoListenerlookslikeaclass?{};//哎呀,itisaninterface如果代码的可读性还不够打动你,那么想象一下这个场景,你的同事说他修复了两个空指针问题,请帮助CodeReview,你查看了这个文件的修订历史,乍一看有很多变化,好像是一个大动作。但实际上,大部分的改动都是代码格式的调整,只有两个改动涉及到需要Review的问题。(貌似是这个同事的IDE自动缩进设置不同,导致所有行都缩进)出现以上问题影响工作效率的原因是团队没有重视CodeStyle,没有把它当做一个工程实践既没有达成协议也没有正确使用工具来帮助其实施。2.然后按照工程实践的标准,实现CodeStyle。本文将重点介绍Java项目中CodeStyle的工具支持,但在此之前,您的团队需要共同做出一些决定:1.使用哪种CodeStyle?每个人都可能有偏好的风格,但在团队合作面前,需要做出一定的妥协。有些公司或组织有统一的CodeStyle指南,小龟草是个不错的选择(但要确保这样的统一指南是参考开发者的意见制定的,实用),你的团队也可以自己Cut,但是至少确保在项目(存储库)级别使用相同的样式。2.不符合CodeStyle的提交如何处理?人们往往在事后补救的方式上懈怠。我的建议是不要让不符合协议的代码流入代码库。对于遗留项目,尤其是大型项目,可以选择部分代码作为实施范围,重点修复Style问题,然后严格实施。不要操之过急,最后全队精疲力尽,只好作罢。我们都知道人工监督是不可持续和不可靠的,所以让我们来看看一些可以提供帮助的工具。3、懒惰是第一生产力。工程实践离不开自动化工具的支持。在Java生态中,最著名的CodeStyle工具应该就是Checkstyle了。它可以通过外部DSL以XML的形式定义代码风格检查风格。例如,您可以在此处找到Google的JavaCheckstyle配置文件。这里就不详细介绍Checkstyle本身了。相反,我将更多地讨论如何工程化地使用Checkstyle。我们可以在交付代码的各种活动中使用Checkstyle来检查360°无死角。(与CodeStyle相关的代码交付生命周期)1.保留提交的质量关口为了执行不让不符合约定的代码流入代码库的决定,可以先设置提交的检查关口服务器端的代码风格。(提交代码时优先考虑服务端检查,可以考虑使用CI服务器来实现)2、从实现层面来说,有两种方式:一种是在SCM上设置检查(来源控制管理,如Git/SVN)服务器项,如果不符合标准,会拒绝提交,但是这种方式实现起来比较困难,一般的SCM服务器不是开发团队管理的,所以不灵活,设置不方便。二是使用持续集成服务器。开发团队的每一次提交都会触发一次构建。我们可以将Checkstyle检查添加到构建脚本中。如果有不合标准的代码,构建就会失败,从而告诉提交者立即修复Style问题。我比较推荐这个方案,因为相关工具支持非常成熟,实现简单,构建过程可以在开发者本地环境中复制,使得Checkstyle检查可以在后续的改进中前移,提供更快的反馈。如果团队使用Maven/Gradle等构建工具,Checkstyle检查可以作为插件实现,嵌入到整个构建过程中。这样CI服务器只需要调用构建脚本。4.VerifyStylelocallyonthedeveloper(在开发者本地实现验证,将反馈闸门前移)。实现CI验证后,就可以开始对开发者实现本地验证了,这样开发者就不用等到代码提交到服务器后才能得到反馈。由于之前使用了构建工具的插件方案,开发者可以通过在本地运行构建来实现验证。比如Gradle提供了Checkstyle插件支持,你可以在这里找到GradleCheckstylePlugin的详细配置文档,如果你使用Maven,可以参考这里。现在只需要一条命令,开发者可以在本地长期验证代码风格。(也可以点击左下角阅读原文,查看完整代码示例)本地验证很好,但我有时会忘记实现它。(让机器做杂事)有时,开发人员在修改代码后,忘记进行本地检查,然后提交代码。最好在提交代码之前自动执行检查。如果你使用Git,你可能会想到Gitcommithook,比如这是我常用的pre-commithook#!/bin/sh#Fromgistathttps://gist.github.com/chadmaughan/5889802#stashanyunstagedchangesgitstash-q--keep-index#runthetestswiththegradlewrapper./gradlewcleanbuild#storethelastexitcodeinavariableRESULT=$?#unstashtheunstashedchangesgitstashpop-q#returnthe'./gradlewbuild'exitcodeexit$RESULT将脚本复制到.git/hooks/,执行gitcommit时会自动触发检查,如果检查失败则提交失败。但是问题是.git无法提交到远程代码仓库,那么除了手动分发和复制之外,有没有更好的办法在团队中共享这个机制呢?曲线救国!将pre-commit放入版本控制中(比如下面的config/pre-commit),然后利用构建工具的扩展机制自动完成复制工作,可以间接实现团队间githooks的共享。#build.gradletaskinstallGitHooks(type:Copy){//将pre-commit从newFile(rootProject.rootDir,'config/pre-commit')复制到{newFile(rootProject.rootDir,'.git/hooks')}fileMode0755}build.dependsOninstallGitHooks//设置执行构建任务时自动触发installGitHooks任务。反馈被提前到编辑时间并可视化。幸运的是,Checkstyle的生态系统非常成熟,所有主流的IDE都有插件支持。以IntellijIdea为例,可以使用checkstyle-idea插件,让团队成员手动设置插件,使用项目的checkstyle配置文件。还没找到自动化配置的方法,也许gradleidea插件可以?)(checkstyle-idea插件配置及效果)有自动实时检测,最好把IDE的自动格式化和Checkstyle配置文件联系起来,否则会被自动格式化,反而给您带来麻烦。(导入IDE的checkstyle配置文件作为自动格式化的依据)如果懒得按自动格式化,可以试试SaveActions插件,它可以在Intellij保存文件时自动进行代码格式化等动作。(本插件目前部分文件存在一些问题,可通过文件路径排除忽略)六、总结1、CodeStyle影响工作效率,团队应作为工程实践予以重视。2.CodeStyle不能靠人工监督检查。应该提供端到端的工具,支持开发环境检查(使用各个构建工具的Checkstyle插件),自动提交检查(gitpre-commithook和分享)IDE增强(checkstyle插件实时可视化)feedback/Automatic自动格式化!)以上工具必须基于同一个Checkstyle配置文件,并纳入版本控制。希望以上技巧可以拯救JavaCodeStyle强迫症。【本文为专栏作家《ThoughtWorks》原创稿件,微信公众号:Thinkworker,转载请联系原作者】点此查看该作者更多好文