强制代码重新格式化的优缺点


19

我目前在一个可能正在强迫开发人员在版本控制签入中使用自动代码格式化程序的地方工作。我正在寻找开发人员关于这样做的优缺点的意见……您认为这对开发人员有何帮助或阻碍。我的具体案例涉及Java / JSP,但我认为该问题可能适用于任何语言。


JSP自动重新格式化?其中包括HTML / XML代码和重新格式化,可以很容易地中断/更改结果输出。
edA-qa mort-ora-y

Answers:


23

我认为这样做非常重要。原因如下:

  • 它使您的源代码控制差异显示实际的代码更改,并且几乎消除了由于空格和其他无关紧要的格式选择而引起的“差异噪声”
  • 它使所有代码更加相似,从而使开发人员可以更轻松地配对和共享代码库

如果这样做,我建议大家将所有代码都签入,然后由一个人对整个代码库进行重新格式化,然后全部重新签入,这样就设置了一个“巨大”的格式更改集(每个人都可以忽略),但是之后,所有差异都是真实的代码差异。

如果您一点一点地做,您将把真正的代码更改与格式更改混合在一起,在更改区域中不必要的事情会变得混乱。


1
我同意,应对全球变化确实是最好的方法。完成它,而无需再担心它。
Patrick Hughes

...直到您更改样式约定。
Nerdfest

1
@Nerdfest然后,您可以在一次提交中将新约定应用于所有项目。没什么大不了的。
gizmo

2
如果您的“ diff”工具无法正确处理空白更改,则很烂。
edA-qa mort-ora-y

2
总是会有例外,即稍微不同的格式可能比指定样式更干净。因此,自动转换通常可以隐藏某些代码块的意图,这实际上与在代码中添加缺陷一样好。
edA-qa mort-ora-y

10

我将在这里提出自己的答案,因为人们似乎只是在增加优势。我认为缺点是:

  • 与自动格式化程序相比,消除了“更好”的功能...它将撤消更清晰的格式化。例如基于列的参数声明,对象的离散添加列表等。
  • 抵抗更改样式约定,因为这些约定现在会造成较大的误导差异更改。
  • 删除了执行任何“特殊情况”格式的功能,而其他格式将使代码更具可读性。
  • 它使您可以使用IDE,这些IDE 完全支持所需的重新格式化功能。在另一个IDE中,缺少所需的选项之一,它将至少引起一些问题。
  • 与外部组共享可写代码存储库会变得很麻烦,除非它们使用与您的组完全相同的格式约定(它们通常会,但并非总是如此)。
  • 总是会有例外,即稍微不同的格式可能比指定样式更干净。因此,自动转换通常可以隐藏某些代码块的意图,这实际上与在代码中添加缺陷一样好。

简而言之,一组非自动化的约定设置了最低的样式/可读性要求,而自动化的约定则设置了一个最小值和一个最大值。

我记得看过VB(也许是第5版)后发现,它最烦人的事情之一是它将强制重新格式化我的代码并删除基本格式以外的内容。


一种格式约定优于另一种格式约定,如果以牺牲一致性为代价,则几乎没有任何好处。您已经习惯了。遵循Bohemian的建议并创建宽限期,以帮助确定格式样式,然后坚持使用。无论如何都不应该轻易更改格式。
JeffO 2011年

3
@Jeff,我不相信他提倡不一致的代码格式,而是提倡难以自动化的一致代码格式。例如,当您有几行相关数据在一起时,许多编码样式都以美观的方式指定对齐列。这极大地提高了可读性,但是很难自动化“美学”或“相关”的定义。这就是某些代码格式化程序将允许在某些情况下覆盖手动格式化的原因。
Karl Bielefeldt

1
最好是在99.9%的时间内拥有一致的格式并忍受您个人不喜欢的奇数位,而不是忍受无序的混搭。我大概取决于团队的纪律所在。如果您遵循某种语言的既定规范,那么所有体面的编辑者/ IDE都可以采用这种格式进行格式化。如果您坚持不遵守规范,就会遇到麻烦。
mattnz'7

3

我发现强制代码格式很棒。它使开发人员可以遍历整个代码集,而不会无所事事。同时制定此标准还有助于新手开发人员养成不良习惯。


3

主要缺点是在真正重要的地方丢失了自定义格式。

想象一个典型的健全性检查if(),如果存在任何特定条件但不满足,它将失败。

  if(
      (user.id == TEST_ID)
    ||(
         (user.id == UserID)
       &&( 
             ( user.type == HUMAN_USER && user.name.size() >= MIN_NAME )
           ||( user.type == EMULATION && input.source != SOURCE_INTERNAL ))
       && ( user.email == NULL || emailValidator.isValid(user.email))
       && ( (user.phone == NULL) == (user.type == EMULATION) )

       // several more lines like this.)
    ){ /* handle results */ }

由于遵循条件逻辑结构的合理缩进,因此这是可读的。

现在,您的自动化工具不知道将不同条件逻辑分隔为相关行的线索。它没有理由将每个簇3-4个条件排成一行并将下一个条件分成两半。或将其拆分,每行一个比较表达式。它甚至在屏幕上看起来更漂亮,但是逻辑将丢失。


这是一团糟,我的正电子大脑刚刚融化。与(和)周围的空白非常不一致。这就是为什么我们需要机器来格式化代码的原因。而且,您始终可以在行前/行后放置单行注释(取决于您的约定)来强制条件分组。在此行注释中,向读者解释这种情况背后的业务规则也将很有帮助。
斯特凡Oravec

@ŠtefanOravec:通过自动格式化程序运行此命令并应用这些注释。看看它是否更具可读性。测试用户-始终。具有有效用户名的人工用户。模拟用户-仅外部来源。电子邮件(如果存在)必须有效。人类用户必须具有电话号码;模拟-一定不能。查看单行注释如何与自动格式化的代码对齐。
SF。

2

我添加了一个不利条件的答案,同时我还将介绍我认为是很大的优势。

当您在提交时使用自动代码重新格式化时,它实际上确实打开了个人喜好变化的可能性,而不会给您的喜好带来他人的通常影响。您可以在提交时使IDE格式代码符合通用标准,但是可以以您喜欢的格式向您显示它,而不会影响其他代码。

对我来说,这几乎是基于约定的编码的圣杯……您可以享受通用代码格式的优点,但仍然可以支持个人喜好而不会产生冲突。


0

这取决于您的需求,但是有些约束是很有用的,例如,每个if()后面都应使用花括号,因为在重构时很容易得到这样的if if错误。

考虑这种情况:

if( x == 0 ) 
   return foo;
//do something else
return bar;

如果现在想在if情况下添加一些日志记录,则可能会意外地写:

if( x == 0 ) 
  log.info("x was 0");
  return foo;
//do something else
return bar;

突然,您的方法总是返回foo

编辑:这不是自动格式化,而是样式检查。很抱歉,如果该答案也离题。:)


这更多的是代码风格的事情,而不是格式化的事情。有用于此的构建工具。

@波西米亚人,你是对的,我看错了这个问题。我们选择的构建工具是checkstyle btw。:)
Thomas

0

它极大地有助于统一公司中的代码,因此,您通常可以为您的产品提供更易于理解和更易于维护的结构。


0

好吧,优点与任何代码格式化程序都一样,例如代码的标准化,开发人员之间的语义等。我看到的唯一可能的缺点是格式化缺乏肉眼,添加了一些异常等。
所以我最好考虑使用IDE格式化程序而不是签入时间格式化程序。


0

以我的经验,这是一件好事。没有一个,代码比较通常会显示出一堆空白格式,并且可能隐藏实际的代码更改。根据我的经验,弄清楚某人的格式并不是罪过,特别是因为整个团队保持一致的潜在好处。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.